Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
text/plain
.txt .text .js .vbs .asp .cgi .pl
----
text/html
.htm .html .hta .htx .mht
----
text/comma-separated-values
.csv
----
text/javascript
.js
----
text/css
.css
----
text/xml
.xml .xsl .xslt
----
image/gif
.gif
----
image/jpeg
.jpg .jpe .jpeg
----
image/png
.png
----
image/bmp
.bmp
----
image/svg+xml
.svg
----
image/tiff
.tif .tiff
----
audio/basic
.au .snd
----
audio/wav
.wav
----
audio/x-pn-realaudio
.ra .rm .ram
----
audio/x-midi
.mid .midi
----
audio/mp3
.mp3
----
audio/m3u
.m3u
----
video/x-ms-asf
.asf
----
video/avi
.avi
----
video/mpeg
.mpg .mpeg
----
video/quicktime
.qt .mov .qtvr
----
application/pdf
.pdf
----
application/rtf
.rtf
----
application/postscript
.ai .eps .ps
----
application/wordperfect
.wpd
----
application/mswrite
.wri
----
application/msexcel
.xls .xls3 .xls4 .xls5 .xlw
----
application/msword
.doc
----
application/mspowerpoint
.ppt .pps
----
application/x-director
.swa
----
application/x-shockwave-flash
.swf
----
application/x-zip-compressed
.zip
----
application/x-gzip
.gz
----
application/x-rar-compressed
.rar
----
application/octet-stream
.com .exe .dll .ocx
----
application/java-archive
.jar
----
application/x-font-otf
.otf
----
application/x-font-ttf
.ttf .ttc
/***
|Name|AttachFilePlugin|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|AttachFilePluginFormatters, AttachFileMIMETypes|
|Description|Store binary files as base64-encoded tiddlers with fallback links for separate local and/or remote file storage|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
!!!!!Documentation
>see [[AttachFilePluginInfo]]
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Revisions
<<<
2011.02.14 4.0.1 fix OSX error: use picker.file.path
2009.06.04 4.0.0 changed attachment storage format to use //sections// instead of embedded substring markers.
|please see [[AttachFilePluginInfo]] for additional revision details|
2005.07.20 1.0.0 Initial Release
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePlugin= {major: 4, minor: 0, revision: 1, date: new Date(2011,2,14)};
// shadow tiddler
config.shadowTiddlers.AttachFile="<<attach inline>>";
// add 'attach' backstage task (insert before built-in 'importTask')
if (config.tasks) { // for TW2.2b or above
config.tasks.attachTask = {
text: "attach",
tooltip: "Attach a binary file as a tiddler",
content: "<<attach inline>>"
}
config.backstageTasks.splice(config.backstageTasks.indexOf("importTask"),0,"attachTask");
}
config.macros.attach = {
// // lingo
//{{{
label: "attach file",
tooltip: "Attach a file to this document",
linkTooltip: "Attachment: ",
typeList: "AttachFileMIMETypes",
titlePrompt: " enter tiddler title...",
MIMEPrompt: "<option value=''>select MIME type...</option><option value='editlist'>[edit list...]</option>",
localPrompt: " enter local path/filename...",
URLPrompt: " enter remote URL...",
tiddlerErr: "Please enter a tiddler title",
sourceErr: "Please enter a source path/filename",
storageErr: "Please select a storage method: embedded, local or remote",
MIMEErr: "Unrecognized file format. Please select a MIME type",
localErr: "Please enter a local path/filename",
URLErr: "Please enter a remote URL",
fileErr: "Invalid path/file or file not found",
tiddlerFormat: '!usage\n{{{%0}}}\n%0\n!notes\n%1\n!type\n%2\n!file\n%3\n!url\n%4\n!data\n%5\n',
//}}}
// // macro definition
//{{{
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleAttachPanel); return; }
var id=params.shift();
this.createAttachPanel(place,id+"_attachPanel",params);
document.getElementById(id+"_attachPanel").style.position="static";
document.getElementById(id+"_attachPanel").style.display="block";
},
//}}}
//{{{
createAttachPanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length) var panel_id="_attachPanel";
// remove existing panel (if any)
var panel=document.getElementById(panel_id); if (panel) panel.parentNode.removeChild(panel);
// set styles for this panel
setStylesheet(this.css,"attachPanel");
// create new panel
var title=""; if (params && params[0]) title=params.shift();
var types=this.MIMEPrompt+this.formatListOptions(store.getTiddlerText(this.typeList)); // get MIME types
panel=createTiddlyElement(place,"span",panel_id,"attachPanel",null);
var html=this.html.replace(/%id%/g,panel_id);
html=html.replace(/%title%/g,title);
html=html.replace(/%disabled%/g,title.length?"disabled":"");
html=html.replace(/%IEdisabled%/g,config.browser.isIE?"disabled":"");
html=html.replace(/%types%/g,types);
panel.innerHTML=html;
if (config.browser.isGecko) { // FF3 FIXUP
document.getElementById("attachSource").style.display="none";
document.getElementById("attachFixPanel").style.display="block";
}
return panel;
},
//}}}
//{{{
toggleAttachPanel:
function (e) {
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_attachPanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.attach.createAttachPanel(parent,"_attachPanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
//}}}
//{{{
formatListOptions:
function(text) {
if (!text || !text.trim().length) return "";
// get MIME list content from text
var parts=text.split("\n----\n");
var out="";
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift(); // 1st line=display text
var value=lines.shift(); // 2nd line=item value
out +='<option value="%1">%0</option>'.format([label,value]);
}
return out;
},
//}}}
// // interface definition
//{{{
css:
".attachPanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em; text-align:left }\
.attachPanel form { display:inline;border:0;padding:0;margin:0; }\
.attachPanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.attachPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.attachPanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.attachPanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.attachPanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.attachPanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; }\
.attachPanel .chk { width:auto;border:0; }\
.attachPanel .btn { width:auto; }\
.attachPanel .btn2 { width:49%; }\
",
//}}}
//{{{
html:
'<form>\
attach from source file\
<input type="file" id="attachSource" name="source" size="56"\
onChange="config.macros.attach.onChangeSource(this)">\
<div id="attachFixPanel" style="display:none"><!-- FF3 FIXUP -->\
<input type="text" id="attachFixSource" style="width:90%"\
title="Enter a path/file to attach"\
onChange="config.macros.attach.onChangeSource(this);">\
<input type="button" style="width:7%" value="..."\
title="Enter a path/file to attach"\
onClick="config.macros.attach.askForFilename(document.getElementById(\'attachFixSource\'));">\
</div><!--end FF3 FIXUP-->\
<div class="box">\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
embed data <input type=checkbox class=chk name="useData" %IEdisabled% \
onclick="if (!this.form.MIMEType.value.length)\
this.form.MIMEType.selectedIndex=this.checked?1:0; "> \
</td><td style="border:0">\
<select size=1 name="MIMEType" \
onchange="this.title=this.value; if (this.value==\'editlist\')\
{ this.selectedIndex=this.form.useData.checked?1:0; story.displayTiddler(null,config.macros.attach.typeList,2); return; }">\
<option value=""></option>\
%types%\
</select>\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
local link <input type=checkbox class=chk name="useLocal"\
onclick="this.form.local.value=this.form.local.defaultValue=this.checked?config.macros.attach.localPrompt:\'\';"> \
</td><td style="border:0">\
<input type=text name="local" size=15 autocomplete=off value=""\
onchange="this.form.useLocal.checked=this.value.length" \
onkeyup="this.form.useLocal.checked=this.value.length" \
onfocus="if (!this.value.length) this.value=config.macros.attach.localPrompt; this.select()">\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
remote link <input type=checkbox class=chk name="useURL"\
onclick="this.form.URL.value=this.form.URL.defaultValue=this.checked?config.macros.attach.URLPrompt:\'\';\"> \
</td><td style="border:0">\
<input type=text name="URL" size=15 autocomplete=off value=""\
onfocus="if (!this.value.length) this.value=config.macros.attach.URLPrompt; this.select()"\
onchange="this.form.useURL.checked=this.value.length;"\
onkeyup="this.form.useURL.checked=this.value.length;">\
</td></tr></table>\
</div>\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;vertical-align:top;width:1%;white-space:nowrap">\
notes \
</td><td style="border:0" colspan=2>\
<textarea name="notes" style="width:98%;height:3.5em;margin-bottom:2px"></textarea>\
</td><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
attach as \
</td><td style="border:0" colspan=2>\
<input type=text name="tiddlertitle" size=15 autocomplete=off value="%title%"\
onkeyup="if (!this.value.length) { this.value=config.macros.attach.titlePrompt; this.select(); }"\
onfocus="if (!this.value.length) this.value=config.macros.attach.titlePrompt; this.select()" %disabled%>\
</td></tr></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
add tags \
</td><td style="border:0">\
<input type=text name="tags" size=15 autocomplete=off value="" onfocus="this.select()">\
</td><td style="width:40%;text-align:right;border:0">\
<input type=button class=btn2 value="attach"\
onclick="config.macros.attach.onClickAttach(this)"><!--\
--><input type=button class=btn2 value="close"\
onclick="var panel=document.getElementById(\'%id%\'); if (panel) panel.parentNode.removeChild(panel);">\
</td></tr></table>\
</form>',
//}}}
// // control processing
//{{{
onChangeSource:
function(here) {
var form=here.form;
var list=form.MIMEType;
var theFilename = here.value;
var theExtension = theFilename.substr(theFilename.lastIndexOf('.')).toLowerCase();
// if theFilename is in current document folder, remove path prefix and use relative reference
var h=document.location.href; folder=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
if (theFilename.substr(0,folder.length)==folder) theFilename='./'+theFilename.substr(folder.length);
else theFilename='file:///'+theFilename; // otherwise, use absolute reference
theFilename=theFilename.replace(/\\/g,"/"); // fixup: change \ to /
form.useLocal.checked = true;
form.local.value = theFilename;
form.useData.checked = !form.useData.disabled;
list.selectedIndex=1;
for (var i=0; i<list.options.length; i++) // find matching MIME type
if (list.options[i].value.indexOf(theExtension)!=-1) { list.selectedIndex = i; break; }
if (!form.tiddlertitle.disabled)
form.tiddlertitle.value=theFilename.substr(theFilename.lastIndexOf('/')+1); // get tiddlername from filename
},
//}}}
//{{{
onClickAttach:
function (here) {
clearMessage();
// get input values
var form=here.form;
var src=form.source; if (config.browser.isGecko) src=document.getElementById("attachFixSource");
src=src.value!=src.defaultValue?src.value:"";
var when=(new Date()).formatString(config.macros.timeline.dateFormat);
var title=form.tiddlertitle.value;
var local = form.local.value!=form.local.defaultValue?form.local.value:"";
var url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
var notes = form.notes.value;
var tags = "attachment excludeMissing "+form.tags.value;
var useData=form.useData.checked;
var useLocal=form.useLocal.checked;
var useURL=form.useURL.checked;
var mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
// validate checkboxes and get filename
if (useData) {
if (src.length) { if (!theLocation) var theLocation=src; }
else { alert(this.sourceErr); src.focus(); return false; }
}
if (useLocal) {
if (local.length) { if (!theLocation) var theLocation = local; }
else { alert(this.localErr); form.local.focus(); return false; }
}
if (useURL) {
if (url.length) { if (!theLocation) var theLocation = url; }
else { alert(this.URLErr); form.URL.focus(); return false; }
}
if (!(useData||useLocal||useURL))
{ form.useData.focus(); alert(this.storageErr); return false; }
if (!theLocation)
{ src.focus(); alert(this.sourceErr); return false; }
if (!title || !title.trim().length || title==this.titlePrompt)
{ form.tiddlertitle.focus(); alert(this.tiddlerErr); return false; }
// if not already selected, determine MIME type based on filename extension (if any)
if (useData && !mimetype.length && theLocation.lastIndexOf('.')!=-1) {
var theExt = theLocation.substr(theLocation.lastIndexOf('.')).toLowerCase();
var theList=form.MIMEType;
for (var i=0; i<theList.options.length; i++)
if (theList.options[i].value.indexOf(theExt)!=-1)
{ var mimetype=theList.options[i].text; theList.selectedIndex=i; break; }
}
// attach the file
return this.createAttachmentTiddler(src, when, notes, tags, title,
useData, useLocal, useURL, local, url, mimetype);
},
getMIMEType:
function(src,def) {
var ext = src.substr(src.lastIndexOf('.')).toLowerCase();
var list=store.getTiddlerText(this.typeList);
if (!list || !list.trim().length) return def;
// get MIME list content from tiddler
var parts=list.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var mime=lines.shift(); // 1st line=MIME type
var match=lines.shift(); // 2nd line=matching extensions
if (match.indexOf(ext)!=-1) return mime;
}
return def;
},
createAttachmentTiddler:
function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, noshow) {
if (useData) { // encode the data
if (!mimetype.length) {
alert(this.MIMEErr);
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
return false;
}
var d = this.readFile(src); if (!d) { return false; }
displayMessage('encoding '+src);
var encoded = this.encodeBase64(d);
displayMessage('file size='+d.length+' bytes, encoded size='+encoded.length+' bytes');
}
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=this.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags);
var panel=document.getElementById("attachPanel"); if (panel) panel.style.display="none";
if (!noshow) { story.displayTiddler(null,title); story.refreshTiddler(title,null,true); }
displayMessage('attached "'+title+'"');
return true;
},
//}}}
// // base64 conversion
//{{{
encodeBase64:
function (d) {
if (!d) return null;
// encode as base64
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3="";
var enc1,enc2,enc3,enc4="";
for (var count=0,i=0; i<d.length; ) {
chr1=d.charCodeAt(i++);
chr2=d.charCodeAt(i++);
chr3=d.charCodeAt(i++);
enc1=chr1 >> 2;
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
enc4=chr3 & 63;
if (isNaN(chr2)) enc3=enc4=64;
else if (isNaN(chr3)) enc4=64;
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
}
return out;
},
decodeBase64: function(input) {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3;
var enc1,enc2,enc3,enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input=input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1 << 2) | (enc2 >> 4);
chr2=((enc2 & 15) << 4) | (enc3 >> 2);
chr3=((enc3 & 3) << 6) | enc4;
out=out+String.fromCharCode(chr1);
if (enc3!=64) out=out+String.fromCharCode(chr2);
if (enc4!=64) out=out+String.fromCharCode(chr3);
} while (i<input.length);
return out;
},
//}}}
// // I/O functions
//{{{
readFile: // read local BINARY file data
function(filePath) {
if(!window.Components) { return null; }
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { alert("access denied: "+filePath); return null; }
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(filePath); } catch(e) { alert("cannot read file - invalid path: "+filePath); return null; }
if (!file.exists()) { alert("cannot read file - not found: "+filePath); return null; }
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
inputStream.init(file, 0x01, 00004, null);
var bInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
bInputStream.setInputStream(inputStream);
return(bInputStream.readBytes(inputStream.available()));
},
//}}}
//{{{
writeFile:
function(filepath,data) {
// TBD: decode base64 and write BINARY data to specified local path/filename
return(false);
},
//}}}
//{{{
askForFilename: // for FF3 fixup
function(target) {
var msg=config.messages.selectFile;
if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
// get local path for current document
var path=getLocalPath(document.location.href);
var p=path.lastIndexOf("/"); if (p==-1) p=path.lastIndexOf("\\"); // Unix or Windows
if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
var file=""
var result=window.mozAskForFilename(msg,path,file,true); // FF3 FIXUP ONLY
if (target && result.length) // set target field and trigger handling
{ target.value=result; target.onchange(); }
return result;
}
};
//}}}
//{{{
if (window.mozAskForFilename===undefined) { // also defined by CoreTweaks (for ticket #604)
window.mozAskForFilename=function(msg,path,file,mustExist) {
if(!window.Components) return false;
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, mustExist?nsIFilePicker.modeOpen:nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel)
var result=picker.file.path;
}
catch(ex) { displayMessage(ex.toString()); }
return result;
}
}
//}}}
/***
|Name|AttachFilePluginFormatters|
|Source|http://www.TiddlyTools.com/#AttachFilePluginFormatters|
|Version|4.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1.3|
|Type|plugin|
|Description|run-time library for displaying attachment tiddlers|
Runtime processing for //rendering// attachment tiddlers created by [[AttachFilePlugin]]. Attachment tiddlers are tagged with<<tag attachment>>and contain binary file content (e.g., jpg, gif, pdf, mp3, etc.) that has been stored directly as base64 text-encoded data or can be loaded from external files stored on a local filesystem or remote web server. Note: after creating new attachment tiddlers, you can remove [[AttachFilePlugin]], as long as you retain //this// tiddler (so that images can be rendered later on).
!!!!!Formatters
<<<
This plugin extends the behavior of the following TiddlyWiki core "wikify()" formatters:
* embedded images: {{{[img[tooltip|image]]}}}
* linked embedded images: {{{[img[tooltip|image][link]]}}}
* external/"pretty" links: {{{[[label|link]]}}}
''Please refer to AttachFilePlugin (source: http://www.TiddlyTools.com/#AttachFilePlugin) for additional information.''
<<<
!!!!!Revisions
<<<
2009.10.10 [4.0.1] in fileExists(), check for IE to avoid hanging Chrome during startup
2009.06.04 [4.0.0] changed attachment storage format to use //sections// instead of embedded substring markers.
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.10.29 [3.7.0] more code reduction: removed upload handling from AttachFilePlugin (saves ~7K!)
2007.10.28 [3.6.0] removed duplicate formatter code from AttachFilePlugin (saves ~10K!) and updated documentation accordingly. This plugin ([[AttachFilePluginFormatters]]) is now //''required''// in order to display attached images/binary files within tiddler content.
2006.05.20 [3.4.0] through 2007.03.01 [3.5.3] sync with AttachFilePlugin
2006.05.13 [3.2.0] created from AttachFilePlugin v3.2.0
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.AttachFilePluginFormatters= {major: 4, minor: 0, revision: 1, date: new Date(2009,10,10)};
//}}}
//{{{
if (config.macros.attach==undefined) config.macros.attach= { };
//}}}
//{{{
if (config.macros.attach.isAttachment==undefined) config.macros.attach.isAttachment=function (title) {
var tiddler = store.getTiddler(title);
if (tiddler==undefined || tiddler.tags==undefined) return false;
return (tiddler.tags.indexOf("attachment")!=-1);
}
//}}}
//{{{
// test for local file existence - returns true/false without visible error display
if (config.macros.attach.fileExists==undefined) config.macros.attach.fileExists=function(f) {
if(window.Components) { // MOZ
try { netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); }
catch(e) { return false; } // security access denied
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
try { file.initWithPath(f); }
catch(e) { return false; } // invalid directory
return file.exists();
}
else if (config.browser.isIE) { // IE
var fso = new ActiveXObject("Scripting.FileSystemObject");
return fso.FileExists(f);
}
else return true; // other browsers: assume file exists
}
//}}}
//{{{
if (config.macros.attach.getAttachment==undefined) config.macros.attach.getAttachment=function(title) {
// extract embedded data, local and remote links (if any)
var text=store.getTiddlerText(title,'');
var embedded=store.getTiddlerText(title+'##data','').trim();
var locallink=store.getTiddlerText(title+'##file','').trim();
var remotelink=store.getTiddlerText(title+'##url','').trim();
// backward-compatibility for older attachments (pre 4.0.0)
var startmarker="---BEGIN_DATA---\n";
var endmarker="\n---END_DATA---";
var pos=0; var endpos=0;
if ((pos=text.indexOf(startmarker))!=-1 && (endpos=text.indexOf(endmarker))!=-1)
embedded="data:"+(text.substring(pos+startmarker.length,endpos)).replace(/\n/g,'');
if ((pos=text.indexOf("/%LOCAL_LINK%/"))!=-1)
locallink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
if ((pos=text.indexOf("/%REMOTE_LINK%/"))!=-1)
remotelink=text.substring(text.indexOf("|",pos)+1,text.indexOf("]]",pos));
// if there is a data: URI defined (not supported by IE)
if (embedded.length && !(config.browser.isIE && parseInt(config.browser.ieVersion[1]) < 9)) return embedded;
// document is being served remotely... use remote URL (if any) (avoids security alert)
if (remotelink.length && document.location.protocol!="file:")
return remotelink;
// local link only... return link without checking file existence (avoids security alert)
if (locallink.length && !remotelink.length)
return locallink;
// local link, check for file exist... use local link if found
if (locallink.length) {
locallink=locallink.replace(/^\.[\/\\]/,''); // strip leading './' or '.\' (if any)
if (this.fileExists(getLocalPath(locallink))) return locallink;
// maybe local link is relative... add path from current document and try again
var pathPrefix=document.location.href; // get current document path and trim off filename
var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\");
if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
if (this.fileExists(getLocalPath(pathPrefix+locallink))) return locallink;
}
// no embedded data, no local (or not found), fallback to remote URL (if any)
if (remotelink.length) return remotelink;
// attachment URL doesn't resolve, just return input as is
return title;
}
//}}}
//{{{
if (config.macros.attach.init_formatters==undefined) config.macros.attach.init_formatters=function() {
if (this.initialized) return;
// find the formatter for "image" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="image"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) // Simple bracketted link
{
var e = w.output;
if(lookaheadMatch[5])
{
var link = lookaheadMatch[5];
// ELS -------------
var external=config.formatterHelpers.isExternalLink(link);
if (external)
{
if (config.macros.attach.isAttachment(link))
{
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title = config.macros.attach.linkTooltip + link;
}
else
e = createExternalLink(w.output,link);
}
else
e = createTiddlyLink(w.output,link,false,null,w.isStatic);
// ELS -------------
addClass(e,"imageLink");
}
var img = createTiddlyElement(e,"img");
if(lookaheadMatch[1])
img.align = "left";
else if(lookaheadMatch[2])
img.align = "right";
if(lookaheadMatch[3])
img.title = lookaheadMatch[3];
img.src = lookaheadMatch[4];
// ELS -------------
if (config.macros.attach.isAttachment(lookaheadMatch[4]))
img.src=config.macros.attach.getAttachment(lookaheadMatch[4]);
// ELS -------------
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
//}}}
//{{{
// find the formatter for "prettyLink" and replace the handler
for (var i=0; i<config.formatters.length && config.formatters[i].name!="prettyLink"; i++);
if (i<config.formatters.length) {
config.formatters[i].handler=function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var e;
var text = lookaheadMatch[1];
if(lookaheadMatch[3]) {
// Pretty bracketted link
var link = lookaheadMatch[3];
if (config.macros.attach.isAttachment(link)) {
e = createExternalLink(w.output,link);
e.href=config.macros.attach.getAttachment(link);
e.title=config.macros.attach.linkTooltip+link;
}
else e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link))
? createExternalLink(w.output,link)
: createTiddlyLink(w.output,link,false,null,w.isStatic);
} else {
e = createTiddlyLink(w.output,text,false,null,w.isStatic);
}
createTiddlyText(e,text);
w.nextMatch = this.lookaheadRegExp.lastIndex;
}
}
} // if "prettyLink" formatter found
this.initialized=true;
}
//}}}
//{{{
config.macros.attach.init_formatters(); // load time init
//}}}
//{{{
if (TiddlyWiki.prototype.coreGetRecursiveTiddlerText==undefined) {
TiddlyWiki.prototype.coreGetRecursiveTiddlerText = TiddlyWiki.prototype.getRecursiveTiddlerText;
TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth) {
return config.macros.attach.isAttachment(title)?
config.macros.attach.getAttachment(title):this.coreGetRecursiveTiddlerText.apply(this,arguments);
}
}
//}}}
/***
|Name|AttachFilePluginInfo|
|Source|http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Documentation for AttachFilePlugin|
Store or link binary files (such as jpg, gif, pdf or even mp3) within your TiddlyWiki document and then use them as images or links from within your tiddler content.
!!!!!Inline interface (live)
>see [[AttachFile]] (shadow tiddler)
><<tiddler AttachFile>>
!!!!!Syntax
<<<
''To display the attach file control panel, simply view the [[AttachFile]] shadow tiddler that is automatically created by the plugin, and contains an instance of the inline control panel.''. Or, you can write:
{{{
<<attach inline>>
}}}
in any tiddler to display the control panel embedded within that tiddler. Note: you can actually use any unique identifier in place of the "inline" keyword. Each unique id creates a separate instance of the controls. If the same ID is used in more than one tiddler, then the control panel is automatically moved to the most recently rendered location. Or, you can write:
{{{
<<attach>>
}}}
(with no ID parameter) in SidebarOptions. This adds a command link that opens the controls as a floating panel, positioned directly to the left of the sidebar.
<<<
!!!!!Usage
<<<
Binary file content can be stored in three different locations:
#embedded in the attachment tiddler (encoded as base64)
#on your filesystem (a 'local link' path/filename)
#on a web server (a 'remote link' URL)
The plugin creates an "attachment tiddler" for each file you attach. Regardless of where you store the binary content, your document can refer to the attachment tiddler rather than using a direct file or URL reference in your embedded image or external links, so that changing document locations will not require updating numerous tiddlers or copying files from one system to another.
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
When you attach a file, a tiddler (tagged with<<tag attachment>>) is generated (using the source filename as the tiddler's title). The tiddler contains //''base64 text-encoded binary data''//, surrounded by {{{/%...%/}}} comment markers (so they are not visible when viewing the tiddler). The tiddler also includes summary details about the file: when it was attached, by whom, etc. and, if the attachment is an image file (jpg, gif, or png), the image is automatically displayed below the summary information.
>Note: although you can edit an attachment tiddler, ''don't change any of the encoded content below the attachment header'', as it has been prepared for use in the rest of your document, and even changing a single character can make the attachment unusable. //If needed, you ''can'' edit the header information or even the MIME type declaration in the attachment data, but be very careful not to change any of the base64-encoded binary data.//
Unfortunately, embedding just a few moderately-sized binary files using base64 text-encoding can dramatically increase the size of your document. To avoid this problem, you can create attachment tiddlers that define external local filesystem (file://) and/or remote web server (http://) 'reference' links, without embedding the binary data directly in the tiddler (i.e., uncheck "embed data" in the 'control panel').
These links provide an alternative source for the binary data: if embedded data is not found (or you are running on Internet Explorer, which does not currently support using embedded data), then the plugin tries the local filesystem reference. If a local file is not found, then the remote reference (if any) is used. This "fallback" approach also lets you 'virtualize' the external links in your document, so that you can access very large binary content such as PDFs, MP3's, and even *video* files, by using just a 'remote reference link' without embedding any data or downloading huge files to your hard disk.
Of course, when you //do// download an attached file, the local copy will be used instead of accessing a remote server each time, thereby saving bandwidth and allowing you to 'go mobile' without having to edit any tiddlers to alter the link locations...
<<<
!!!!!Syntax / Examples
<<<
To embed attached files as images or link to them from other tiddlers, use the standard ~TiddlyWiki image syntax ({{{[img[tooltip|filename]]}}}), linked image syntax ({{{[img[tooltip|filename][tiddlername]]}}}) , or "external link" syntax ({{{[[text|URL]]}}}), replacing the filename or URL that is normally entered with the title of an attachment tiddler.
embedded image data:
>{{{[img[Meow|AttachFileSample]]}}}
>[img[Meow|AttachFileSample]]
embedded image data with link to larger remote image:
>{{{[img[click for larger view|AttachFileSample][AttachFileSample2]]}}}
>[img[click for larger view|AttachFileSample][AttachFileSample2]]
'external' link to embedded image data:
>{{{[[click to view attachment|AttachFileSample]]}}}
>[[click to view attachment|AttachFileSample]]
'external' link to remote image:
>{{{[[click to view attachment|AttachFileSample2]]}}}
>[[click to view attachment|AttachFileSample2]]
regular ~TiddlyWiki links to attachment tiddlers:
>{{{[[AttachFileSample]]}}} [[AttachFileSample]]
>{{{[[AttachFileSample2]]}}} [[AttachFileSample2]]
<<<
!!!!!Defining MIME types
<<<
When you select a source file, a ''[[MIME|http://en.wikipedia.org/wiki/MIME]]'' file type is automatically suggested, based on filename extension. The AttachFileMIMETypes tiddler defines the list of MIME types that will be recognized by the plugin. Each MIME type definition consists of exactly two lines of text: the official MIME type designator (e.g., "text/plain", "image/gif", etc.), and a space-separated list of file extensions associated with that type. List entries are separated by "----" (horizontal rules).
<<<
!!!!!Known Limitations
<<<
Internet Explorer does not support the data: URI scheme, and cannot use the //embedded// data to render images or links. However, you can still use the local/remote link definitions to create file attachments that are stored externally. In addition, while it is relatively easy to read local //text// files, reading binary files is not directly supported by IE's FileSystemObject (FSO) methods, and other file I/O techniques are subject to security barriers or require additional MS proprietary technologies (like ASP or VB) that make implementation more difficult. As a result, you cannot //create// new attachment tiddlers using IE.
<<<
!!!!!Installation
<<<
Import (or copy/paste) the following tiddlers into your document:
* [[AttachFilePlugin]] (tagged with <<tag systemConfig>>)
* [[AttachFilePluginFormatters]] ("runtime distribution library") (tagged with <<tag systemConfig>>)
* [[AttachFileSample]] and [[AttachFileSample2]] //(tagged with <<tag attachment>>)//
* [[AttachFileMIMETypes]] //(defines binary file types)//
> Important note: As of version 3.6.0, in order to //render// images and other binary attachments created with this plugin, you must also install [[AttachFilePluginFormatters]], which extends the behavior of the TiddlyWiki core formatters for embedded images ({{{[img[tooltip|image]]}}}), linked embedded images ({{{[img[tooltip|image][link]]}}}), and external/"pretty" links ({{{[[label|link]]}}}), so that these formatter will process references to attachment tiddlers as if a normal file reference had been provided. |
<<<
!!!!!Revisions
<<<
2009.06.04 4.0.0 changed attachment storage format to use //sections// instead of embedded substring markers.
2008.07.21 3.9.0 Fixup for FireFox 3: use HTML with separate text+button control instead of type='file' control
2008.05.12 3.8.1 automatically add 'attach' task to backstage (moved from BackstageTweaks)
2008.04.09 3.8.0 in onChangeSource(), if source matches current document folder, use relative reference for local link. Also, disable 'embed' when using IE (which //still// doesn't support data: URI)
2008.04.07 3.7.3 fixed typo in HTML for 'local file link' so that clicking in input field doesn't erase current path/file (if any)
2008.04.07 3.7.2 auto-create AttachFile shadow tiddler for inline interface
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.12.03 3.7.1 in createAttachmentTiddler(), added optional "noshow" flag to suppress display of newly created tiddlers.
2007.10.29 3.7.0 code reduction: removed support for built-in upload to server... on-line hosting of binary attachments is left to the document author, who can upload/host files using 3rd-party web-based services (e.g. www.flickr.com, ) or stand-alone applications (e.g., FTP).
2007.10.28 3.6.0 code reduction: removed duplicate definition of image and prettyLink formatters. Rendering of attachment tiddlers now //requires// installation of AttachFilePluginFormatters
2007.03.01 3.5.3 use apply() to invoke hijacked function
2007.02.25 3.5.2 in hijack of "prettyLink", fix version check for TW2.2 compatibility (prevent incorrect use of fallback handler)
2007.01.09 3.5.1 onClickAttach() refactored to create separate createAttachmentTiddler() API for use with FileDropPluginHandlers
2006.11.30 3.5.0 in getAttachment(), for local references, add check for file existence and fallback to remote URL if local file not found. Added fileExists() to encapsulate FF vs. IE local file test function (IE FSO object code is TBD).
2006.11.29 3.4.8 in hijack for PrettyLink, 'simple bracketed link' opens tiddler instead of external link to attachment
2006.11.29 3.4.7 in readFile(), added try..catch around initWithPath() to handle invalid/non-existent paths better.
2006.11.09 3.4.6 REAL FIX for TWv2.1.3: incorporate new TW2.1.3 core "prettyLink" formatter regexp handling logic and check for version < 2.1.3 with fallback to old plugin code. Also, cleanup table layout in HTML (added "border:0" directly to table elements to override stylesheet)
2006.11.08 3.4.5 TEMPORARY FIX for TWv2.1.3: disable hijack of wikiLink formatter due to changes in core wikiLink regexp definition. //Links to attachments are broken, but you can still use {{{[img[TiddlerName]]}}} to render attachments as images, as well as {{{background:url('[[TiddlerName]]')}}} in CSS declarations for background images.//
2006.09.10 3.4.4 update formatters for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.07.24 3.4.3 in prettyLink formatter, added check for isShadowTiddler() to fix problem where shadow links became external links.
2006.07.13 3.4.2 in getAttachment(), fixed stripping of newlines so data: used in CSS will work
2006.05.21 3.4.1 in getAttachment(), fixed substring() to extract data: URI (was losing last character, which broken rendering of SOME images)
2006.05.20 3.4.0 hijack core getRecursiveTiddlerText() to support rendering attachments in stylesheets (e.g. {{{url([[AttachFileSample]])}}})
2006.05.20 3.3.6 add "description" feature to easily include notes in attachment tiddler (you can always edit to add them later... but...)
2006.05.19 3.3.5 add "attach as" feature to change default name for attachment tiddlers. Also, new optional param to specify tiddler name (disables editing)
2006.05.16 3.3.0 completed XMLHttpRequest handling for GET or POST to configurable server scripts
2006.05.13 3.2.0 added interface for upload feature. Major rewrite of code for clean object definitions. Major improvements in UI interaction and validation.
2006.05.09 3.1.1 add wikifer support for using attachments in links from "linked image" syntax: {{{[img[tip|attachment1][attachment2]]}}}
2006.05.09 3.1.0 lots of code changes: new options for attachments that use embedded data and/or links to external files (local or remote)
2006.05.03 3.0.2 added {{{/%...%/}}} comments around attachment data to hide it when viewing attachment tiddler.
2006.02.05 3.0.1 wrapped wikifier hijacks in initAttachmentFormatters() function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.27 3.0.0 Update for TW2.0. Automatically add 'excludeMissing' tag to attachments
2005.12.16 2.2.0 Dynamically create/remove attachPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding.
2005.11.20 2.1.0 added wikifier handler extensions for "image" and "prettyLink" to render tiddler attachments
2005.11.09 2.0.0 begin port from old ELS Design adaptation based on ~TW1.2.33
2005.07.20 1.0.0 Initial release (as adaptation)
<<<
/***
|Name|AttachImagePlugin|
|Source|Extension to: http://www.TiddlyTools.com/#AttachFilePlugin|
|Documentation|http://www.TiddlyTools.com/#AttachFilePluginInfo|
|Version|4.0.1|
|Author|Eric Shulman + Petri Salmela|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|AttachFilePlugin, AttachFilePluginFormatters, AttachFileMIMETypes|
|Description|An extension to AttachFilePlugin (restricted interface for images)|
!!!!!Code
***/
// // version
//{{{
// shadow tiddler
config.shadowTiddlers.AttachImageFile="<<attachimage inline>>";
config.macros.attachimage = {
typeList: "AttachimageFileMIMETypes",
label: "attach file",
tooltip: "Attach a file to this document",
linkTooltip: "Attachment: ",
titlePrompt: " enter tiddler title...",
MIMEPrompt: "<option value=''>select MIME type...</option><option value='editlist'>[edit list...]</option>",
localPrompt: " enter local path/filename...",
URLPrompt: " enter remote URL...",
tiddlerErr: "Please enter a tiddler title",
sourceErr: "Please enter a source path/filename",
storageErr: "Please select a storage method: embedded, local or remote",
MIMEErr: "Unrecognized file format. Please select a jpg/png/gif image.",
localErr: "Please enter a local path/filename",
URLErr: "Please enter a remote URL",
fileErr: "Invalid path/file or file not found",
tiddlerFormat: '!usage\n{{{%0}}}\n%0\n!notes\n%1\n!type\n%2\n!file\n%3\n!url\n%4\n!name\n%6\n!author\n%7\n!source\n%8\n!license\n%9\n!data\n%5\n',
css:
".attachimagePanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
font-size: 8pt; line-height:110%; padding: 0.5em; margin:0em; text-align:left;}\
.attachimagePanel form { display:inline;border:0;padding:0;margin:0; }\
.attachimagePanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.attachimagePanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.attachimagePanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.attachimagePanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.attachimagePanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.attachimagePanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; display: none; }\
.attachimagePanel .chk { width:auto;border:0; }\
.attachimagePanel .btn { width:auto; }\
.attachimagePanel .btn2 { width:49%; display: none; }\
.attachimagePanel tr.inputas {display: none;}\
",
html:
'<form>\
attach from source file\
<input type="file" id="attachSource" name="source" size="56"\
onChange="config.macros.attachimage.onChangeSource(this)">\
<div id="attachFixPanel" style="display:none"><!-- FF3 FIXUP -->\
<input type="text" id="attachFixSource" style="width:90%"\
title="Enter a path/file to attach"\
onChange="config.macros.attachimage.onChangeSource(this);">\
<input type="button" style="width:7%" value="..."\
title="Enter a path/file to attach"\
onClick="config.macros.attachimage.askForFilename(document.getElementById(\'attachFixSource\'));">\
</div><!--end FF3 FIXUP-->\
<div class="box">\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
embed data <input type=checkbox class=chk name="useData" %IEdisabled% \
onclick="if (!this.form.MIMEType.value.length)\
this.form.MIMEType.selectedIndex=this.checked?1:0; "> \
</td><td style="border:0">\
<select size=1 name="MIMEType" \
onchange="this.title=this.value; if (this.value==\'editlist\')\
{ this.selectedIndex=this.form.useData.checked?1:0; story.displayTiddler(null,config.macros.attachimage.typeList,2); return; }">\
<option value=""></option>\
%types%\
</select>\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
local link <input type=checkbox class=chk name="useLocal"\
onclick="this.form.local.value=this.form.local.defaultValue=this.checked?config.macros.attachimage.localPrompt:\'\';"> \
</td><td style="border:0">\
<input type=text name="local" size=15 autocomplete=off value=""\
onchange="this.form.useLocal.checked=this.value.length" \
onkeyup="this.form.useLocal.checked=this.value.length" \
onfocus="if (!this.value.length) this.value=config.macros.attachimage.localPrompt; this.select()">\
</td></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
remote link <input type=checkbox class=chk name="useURL"\
onclick="this.form.URL.value=this.form.URL.defaultValue=this.checked?config.macros.attachimage.URLPrompt:\'\';\"> \
</td><td style="border:0">\
<input type=text name="URL" size=15 autocomplete=off value=""\
onfocus="if (!this.value.length) this.value=config.macros.attachimage.URLPrompt; this.select()"\
onchange="this.form.useURL.checked=this.value.length;"\
onkeyup="this.form.useURL.checked=this.value.length;">\
</td></tr></table>\
</div>\
<table style="border:0"><tr style="border:0"><td style="border:0;text-align:right;vertical-align:top;width:1%;white-space:nowrap">\
notes \
</td><td style="border:0" colspan=2>\
<textarea name="notes" style="width:98%;height:3.5em;margin-bottom:2px"></textarea>\
</td><tr class="inputauthor" style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
Author \
</td><td style="border:0" colspan=2>\
<input type=text name="authordata" size=15 autocomplete=off value="" />\
</td><tr class="inputsource" style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
Source \
</td><td style="border:0" colspan=2>\
<input type=text name="sourcedata" size=15 autocomplete=off value="" />\
</td><tr class="inputlicense" style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
License \
</td><td style="border:0" colspan=2>\
<input type=text name="licensedata" size=15 autocomplete=off value="" />\
</td><tr class="inputname" style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
name \
</td><td style="border:0" colspan=2>\
<input type=text name="imagename" size=15 autocomplete=off value="%title%"\
onkeyup="if (!this.value.length) { this.value=config.macros.attachimage.titlePrompt; this.select(); }"\
onfocus="if (!this.value.length) this.value=config.macros.attachimage.titlePrompt; this.select()" %disabled%>\
</td><tr class="inputas" style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
attach as \
</td><td style="border:0" colspan=2>\
<input type=text name="tiddlertitle" size=15 autocomplete=off value="">\
</td></tr></tr><tr style="border:0"><td style="border:0;text-align:right;width:1%;white-space:nowrap">\
add tags \
</td><td style="border:0">\
<input type=text name="tags" size=15 autocomplete=off value="" onfocus="this.select()">\
</td><td style="width:40%;text-align:right;border:0">\
<input type=button class=btn2 value="attach"\
onclick="config.macros.attachimage.onClickAttach(this)"><!--\
<input type=button class=btn2 value="close"\
onclick="var panel=document.getElementById(\'%id%\'); if (panel) panel.parentNode.removeChild(panel);">-->\
</td></tr></table>\
</form>',
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleAttachimagePanel); return; }
var id=params.shift();
this.createAttachimagePanel(place,id+"_attachimagePanel",params);
document.getElementById(id+"_attachimagePanel").style.position="static";
document.getElementById(id+"_attachimagePanel").style.display="block";
},
createAttachimagePanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length) var panel_id="_attachimagePanel";
// remove existing panel (if any)
var panel=document.getElementById(panel_id); if (panel) panel.parentNode.removeChild(panel);
// set styles for this panel
setStylesheet(this.css,"attachimagePanel");
// create new panel
var title=""; if (params && params[0]) title=params.shift();
var types=this.MIMEPrompt+this.formatListOptions(store.getTiddlerText(this.typeList)); // get MIME types
panel=createTiddlyElement(place,"span",panel_id,"attachimagePanel",null);
var html=this.html.replace(/%id%/g,panel_id);
html=html.replace(/%title%/g,title);
html=html.replace(/%disabled%/g,title.length?"disabled":"");
html=html.replace(/%IEdisabled%/g,config.browser.isIE?"disabled":"");
html=html.replace(/%types%/g,types);
panel.innerHTML=html;
if (config.browser.isGecko) { // FF3 FIXUP
// document.getElementById("attachSource").style.display="none";
// document.getElementById("attachFixPanel").style.display="block";
}
return panel;
},
toggleAttachimagePanel:
function (e) {
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_attachimagePanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.attachimage.createAttachimagePanel(parent,"_attachimagePanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
formatListOptions:
function(text) {
if (!text || !text.trim().length) return "";
// get MIME list content from text
var parts=text.split("\n----\n");
var out="";
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift(); // 1st line=display text
var value=lines.shift(); // 2nd line=item value
out +='<option value="%1">%0</option>'.format([label,value]);
}
return out;
},
//}}}
//{{{
onChangeSource:
function(here) {
var form=here.form;
var list=form.MIMEType;
var theFilename = here.value;
var theExtension = theFilename.substr(theFilename.lastIndexOf('.')).toLowerCase();
// if theFilename is in current document folder, remove path prefix and use relative reference
var h=document.location.href; folder=getLocalPath(decodeURIComponent(h.substr(0,h.lastIndexOf("/")+1)));
if (theFilename.substr(0,folder.length)==folder) theFilename='./'+theFilename.substr(folder.length);
else theFilename='file:///'+theFilename; // otherwise, use absolute reference
theFilename=theFilename.replace(/\\/g,"/"); // fixup: change \ to /
// use always path: "./data/images/"
theFilename = './data/images/'+theFilename.substr(theFilename.lastIndexOf('/')+1);
form.useLocal.checked = true;
form.local.value = theFilename;
form.useData.checked = !form.useData.disabled;
list.selectedIndex=1;
for (var i=0; i<list.options.length; i++) // find matching MIME type
if (list.options[i].value.indexOf(theExtension)!=-1) { list.selectedIndex = i; break; }
if (!form.imagename.disabled)
form.imagename.value=theFilename.substr(theFilename.lastIndexOf('/')+1); // get imagename from filename
},
//}}}
//{{{
onClickAttach:
function (here) {
clearMessage();
// get input values
var form=here.form;
var src=form.source; // if (config.browser.isGecko) src=document.getElementById("attachFixSource");
src=src.value!=src.defaultValue?src.value:"";
var when=(new Date()).formatString(config.macros.timeline.dateFormat);
var imagename = form.imagename.value;
var title=form.tiddlertitle.value;
// var local = form.local.value!=form.local.defaultValue?form.local.value:"";
var local = './data/images/'+title;
var url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
var notes = form.notes.value;
var tags = "attachment excludeMissing ebookimage "+form.tags.value;
var useData=form.useData.checked;
var useLocal=form.useLocal.checked;
var useURL=form.useURL.checked;
var mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
var author = form.authordata.value;
var source = form.sourcedata.value;
var license = form.licensedata.value;
// validate checkboxes and get filename
if (useData) {
if (src.length) { if (!theLocation) var theLocation=src; }
else { alert(this.sourceErr); src.focus(); return false; }
}
if (useLocal) {
if (local.length) { if (!theLocation) var theLocation = local; }
else { alert(this.localErr); form.local.focus(); return false; }
}
if (useURL) {
if (url.length) { if (!theLocation) var theLocation = url; }
else { alert(this.URLErr); form.URL.focus(); return false; }
}
if (!(useData||useLocal||useURL))
{ form.useData.focus(); alert(this.storageErr); return false; }
if (!theLocation)
{ src.focus(); alert(this.sourceErr); return false; }
if (!title || !title.trim().length || title==this.titlePrompt)
{ form.tiddlertitle.focus(); alert(this.tiddlerErr); return false; }
// if not already selected, determine MIME type based on filename extension (if any)
if (useData && !mimetype.length && theLocation.lastIndexOf('.')!=-1) {
var theExt = theLocation.substr(theLocation.lastIndexOf('.')).toLowerCase();
var theList=form.MIMEType;
for (var i=0; i<theList.options.length; i++)
if (theList.options[i].value.indexOf(theExt)!=-1)
{ var mimetype=theList.options[i].text; theList.selectedIndex=i; break; }
}
// attach the file
if (store.tiddlerExists(title)){
if (!confirm("Image with this name already exists!\nDo you want to overwrite?")){
return false;
}
}
return this.createAttachmentTiddler(src, when, notes, tags, title,
useData, useLocal, useURL, local, url, mimetype, imagename, author, source, license, true);
},
getMIMEType:
function(src,def) {
var ext = src.substr(src.lastIndexOf('.')).toLowerCase();
var list=store.getTiddlerText(this.typeList);
if (!list || !list.trim().length) return def;
// get MIME list content from tiddler
var parts=list.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var mime=lines.shift(); // 1st line=MIME type
var match=lines.shift(); // 2nd line=matching extensions
if (match.indexOf(ext)!=-1) return mime;
}
return def;
},
createAttachmentTiddler:
function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, imagename, author, source, license, noshow) {
if (useData) { // encode the data
if (!mimetype.length) {
alert(this.MIMEErr);
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
return false;
}
var d = this.readFile(src); if (!d) { return false; }
displayMessage('encoding '+src);
var encoded = this.encodeBase64(d);
displayMessage('file size='+d.length+' bytes, encoded size='+encoded.length+' bytes');
}
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=this.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ,
imagename, author, source, license]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags);
var panel=document.getElementById("attachPanel"); if (panel) panel.style.display="none";
if (!noshow) { story.displayTiddler(null,title); story.refreshTiddler(title,null,true); }
displayMessage('attached "'+title+'"');
return true;
},
//}}}
// // base64 conversion
//{{{
encodeBase64:
function (d) {
if (!d) return null;
// encode as base64
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3="";
var enc1,enc2,enc3,enc4="";
for (var count=0,i=0; i<d.length; ) {
if (typeof(d) !== 'string'){
chr1=d[i++];
chr2=d[i++];
chr3=d[i++];
} else {
chr1=d.charCodeAt(i++);
chr2=d.charCodeAt(i++);
chr3=d.charCodeAt(i++);
}
enc1=chr1 >> 2;
enc2=((chr1 & 3) << 4) | (chr2 >> 4);
enc3=((chr2 & 15) << 2) | (chr3 >> 6);
enc4=chr3 & 63;
if (isNaN(chr2)) enc3=enc4=64;
else if (isNaN(chr3)) enc4=64;
out+=keyStr.charAt(enc1)+keyStr.charAt(enc2)+keyStr.charAt(enc3)+keyStr.charAt(enc4);
chr1=chr2=chr3=enc1=enc2=enc3=enc4="";
}
return out;
},
decodeBase64: function(input) {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out="";
var chr1,chr2,chr3;
var enc1,enc2,enc3,enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input=input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1 << 2) | (enc2 >> 4);
chr2=((enc2 & 15) << 4) | (enc3 >> 2);
chr3=((enc3 & 3) << 6) | enc4;
out=out+String.fromCharCode(chr1);
if (enc3!=64) out=out+String.fromCharCode(chr2);
if (enc4!=64) out=out+String.fromCharCode(chr3);
} while (i<input.length);
return out;
},
//}}}
// // I/O functions
//{{{
readFile: // read local BINARY file data
function(filePath, callback) {
if(!window.Components) { return null; }
var filename = filePath;
var currentpage = window.location.href;
var attachpath = currentpage.substr(0, currentpage.lastIndexOf('/') + 1) + 'attachments/';
filePath = attachpath + filename;
try {
var xmlReq = new XMLHttpRequest();
xmlReq.open('GET', filePath, true);
xmlReq.responseType = 'arraybuffer';
xmlReq.onload = function(e){
var data = new Uint8Array(this.response);
callback(data);
}
xmlReq.send();
} catch (err) {
alert('Could not read file:\n ' + filePath + '\n\nThe attachment must be opened from folder:\n ' + attachpath.replace(/^file:\/*/, '/'));
return false;
}
},
//}}}
//{{{
writeFile:
function(filepath,data) {
// TBD: decode base64 and write BINARY data to specified local path/filename
return(false);
},
//}}}
//{{{
askForFilename: // for FF3 fixup
function(target) {
var msg=config.messages.selectFile;
if (target && target.title) msg=target.title; // use target field tooltip (if any) as dialog prompt text
// get local path for current document
var path=getLocalPath(document.location.href);
var p=path.lastIndexOf("/"); if (p==-1) p=path.lastIndexOf("\\"); // Unix or Windows
if (p!=-1) path=path.substr(0,p+1); // remove filename, leave trailing slash
var file=""
var result=window.mozAskForFilename(msg,path,file,true); // FF3 FIXUP ONLY
if (target && result.length) // set target field and trigger handling
{ target.value=result; target.onchange(); }
return result;
}
}
//}}}
image/gif
.gif
----
image/jpeg
.jpg .jpe .jpeg
----
image/png
.png
----
image/bmp
.bmp
----
image/svg+xml
.svg
Copyright (c) abego Software ~GmbH, 2005-2006 ([[www.abego-software.de|http://www.abego-software.de]])
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<<tiddler [[BSD open source license]]>>
!usage
{{{[img[Book_one_page.png]]}}}
[img[Book_one_page.png]]
!notes
One page book
!type
image/png
!file
./data/images/Book_one_page.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[Book_two_pages.png]]}}}
[img[Book_two_pages.png]]
!notes
Two page book
!type
image/png
!file
./data/images/Book_two_pages.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[CB_logo-300.png]]}}}
[img[CB_logo-300.png]]
!notes
Central Baltic -logo
!type
image/png
!file
!url
!data
data:image/png;base64,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
!Inline Formatting
|!Option|!Syntax|!Output|
|bold font|{{{''bold''}}}|''bold''|
|italic type|{{{//italic//}}}|//italic//|
|underlined text|{{{__underlined__}}}|__underlined__|
|strikethrough text|{{{--strikethrough--}}}|--strikethrough--|
|superscript text|{{{^^super^^script}}}|^^super^^script|
|subscript text|{{{~~sub~~script}}}|~~sub~~script|
|highlighted text|{{{@@highlighted@@}}}|@@highlighted@@|
|preformatted text|<html><code>{{{preformatted}}}</code></html>|{{{preformatted}}}|
!Block Elements
!!Headings
{{{
!Heading 1
!!Heading 2
!!!Heading 3
!!!!Heading 4
!!!!!Heading 5
}}}
<<<
!Heading 1
!!Heading 2
!!!Heading 3
!!!!Heading 4
!!!!!Heading 5
<<<
!!Lists
{{{
* unordered list, level 1
** unordered list, level 2
*** unordered list, level 3
# ordered list, level 1
## ordered list, level 2
### ordered list, level 3
; definition list, term
: definition list, description
}}}
<<<
* unordered list, level 1
** unordered list, level 2
*** unordered list, level 3
# ordered list, level 1
## ordered list, level 2
### ordered list, level 3
; definition list, term
: definition list, description
<<<
!!Blockquotes
{{{
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
<<<
blockquote
<<<
}}}
<<<
> blockquote, level 1
>> blockquote, level 2
>>> blockquote, level 3
> blockquote
<<<
!!Preformatted Text
<html><pre>
{{{
preformatted (e.g. code)
}}}
</pre></html>
<<<
{{{
preformatted (e.g. code)
}}}
<<<
!!Tables
{{{
|CssClass|k
|!heading column 1|!heading column 2|
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
}}}
''Annotation:''
* The {{{>}}} marker creates a "colspan", causing the current cell to merge with the one to the right.
* The {{{~}}} marker creates a "rowspan", causing the current cell to merge with the one above.
<<<
|CssClass|k
|!heading column 1|!heading column 2|
|row 1, column 1|row 1, column 2|
|row 2, column 1|row 2, column 2|
|>|COLSPAN|
|ROWSPAN| … |
|~| … |
|CssProperty:value;…| … |
|caption|c
<<<
!!Images /% TODO %/
cf. [[TiddlyWiki.com|http://www.tiddlywiki.com/#EmbeddedImages]]
!Hyperlinks
* [[WikiWords|WikiWord]] are automatically transformed to hyperlinks to the respective tiddler
** the automatic transformation can be suppressed by preceding the respective WikiWord with a tilde ({{{~}}}): {{{~WikiWord}}}
* [[PrettyLinks]] are enclosed in square brackets and contain the desired tiddler name: {{{[[tiddler name]]}}}
** optionally, a custom title or description can be added, separated by a pipe character ({{{|}}}): {{{[[title|target]]}}}<br>''N.B.:'' In this case, the target can also be any website (i.e. URL).
!Custom Styling
* {{{@@CssProperty:value;CssProperty:value;…@@}}}<br>''N.B.:'' CSS color definitions should use lowercase letters to prevent the inadvertent creation of WikiWords.
* <html><code>{{customCssClass{…}}}</code></html>
* raw HTML can be inserted by enclosing the respective code in HTML tags: {{{<html> … </html>}}}
!Special Markers
* {{{<br>}}} forces a manual line break
* {{{----}}} creates a horizontal ruler
* [[HTML entities|http://www.tiddlywiki.com/#HtmlEntities]]
* {{{<<macroName>>}}} calls the respective [[macro|Macros]]
* To hide text within a tiddler so that it is not displayed, it can be wrapped in {{{/%}}} and {{{%/}}}.<br/>This can be a useful trick for hiding drafts or annotating complex markup.
* To prevent wiki markup from taking effect for a particular section, that section can be enclosed in three double quotes: e.g. {{{"""WikiWord"""}}}.
Background: #eee
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Background: #eee
TiddlerBg: #fff
BorderColor: #aaa
HeaderBg1: #a1ba3f
HeaderBg2: #74862d
HeaderBg: rgba(116,134,45,0.9)
HeaderBgRed: rgba(160,45,45,0.9)
config.options.txtUserKey = "";
//{{{
config.options.chkAutoSave = true;
config.options.chkSaveBackups = false;
config.options.txtMaxEditRows = "30";
//config.options.txtCalFirstDay = "6";
//config.options.txtCalStartOfWeekend = "5";
config.views.wikified.dateFormat = "YYYY-0MM-0DD 0hh:0mm"; // "created" and "modified" timestamps in the tiddler display
config.macros.timeline.dateFormat = "YYYY-0MM-0DD (ddd)"; // dates in the timeline
config.options.chkSinglePageMode=false;
config.options.chkHTMLHideLinebreaks=true;
config.options.txtUserName="";
config.options.txtUserKey="";
//}}}
//{{{
config.options.chkAutoSave = true;
config.options.chkSaveBackups = false;
config.options.txtMaxEditRows = "40";
//config.options.txtCalFirstDay = "6";
//config.options.txtCalStartOfWeekend = "5";
config.views.wikified.dateFormat = "YYYY-0MM-0DD 0hh:0mm"; // "created" and "modified" timestamps in the tiddler display
config.macros.timeline.dateFormat = "YYYY-0MM-0DD (ddd)"; // dates in the timeline
config.options.chkSinglePageMode=false;
config.options.chkHTMLHideLinebreaks=true;
config.options.chkDisableWikiLinks=true;
//}}}
Here are some examples that show the usage of tiddler data, as provided by the DataTiddlerPlugin.
<<forEachTiddler
where
'tiddler.tags.contains("DataTiddlerExample")'
>>
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).
Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers.
''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.
''Access and Modify Tiddler Data''
You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields.
These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//
''Data Representation in a Tiddler''
The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]].
//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}
The data section is not displayed when viewing the tiddler (see also "The showData Macro").
Beside the data section a tiddler may have all kind of other content.
Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.
''Saving Changes''
The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.
''Notifications''
No notifications are sent when a tiddler's data value is changed through the "setData" methods.
''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.
''The showData Macro''
By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:
''Syntax:''
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
!Revision history
* v1.0.6 (2006-08-26)
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed:
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features:
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed:
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// DataTiddlerPlugin
//============================================================================
//============================================================================
// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {
version.extensions.DataTiddlerPlugin = {
major: 1, minor: 0, revision: 6,
date: new Date(2006, 7, 26),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};
// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window;
if (!TiddlyWiki.prototype.getTiddler) {
TiddlyWiki.prototype.getTiddler = function(title) {
var t = this.tiddlers[title];
return (t !== undefined && t instanceof Tiddler) ? t : null;
};
}
//============================================================================
// DataTiddler Class
//============================================================================
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
function DataTiddler() {
}
DataTiddler = {
// Function to stringify a JavaScript value, producing the text for the data section content.
// (Must match the implementation of DataTiddler.parse.)
//
stringify : null,
// Function to parse the text for the data section content, producing a JavaScript value.
// (Must match the implementation of DataTiddler.stringify.)
//
parse : null
};
// Ensure access for IE
window.DataTiddler = DataTiddler;
// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------
// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};
// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler+ "("+t+")";
}
DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};
// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...)
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataObject(t);
};
// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.readDataSectionText(t);
};
// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------
// Internal.
//
// The original JSONError is not very user friendly,
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
if (ex.name == 'JSONError') {
ex.toString = function() {
return ex.name + ": "+ex.message+" ("+ex.text+")";
};
}
return ex;
};
// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
if (t.dataObject === undefined) {
var data = DataTiddler.readData(t);
t.dataObject = (data) ? data : {};
}
return t.dataObject;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
return (value === undefined) ? defaultValue : value;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
var oldValue = data[field];
if (value == defaultValue) {
if (oldValue !== undefined) {
delete data[field];
DataTiddler.save(tiddler);
}
return;
}
data[field] = value;
DataTiddler.save(tiddler);
};
// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
if (matches === null || !matches[2]) {
return null;
}
return matches[2];
};
// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
var text = DataTiddler.readDataSectionText(tiddler);
try {
return text ? DataTiddler.parse(text) : null;
} catch(ex) {
throw DataTiddler.extendJSONError(ex);
}
};
// Internal.
//
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
return DataTiddler.stringify(data);
};
// Internal.
//
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
var index = s.indexOf(subString, startIndex);
while ((index > 0) && (s[index-1] == '~')) {
index = s.indexOf(subString, index+1);
}
return index;
};
// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
// Special care must be taken to handle "<data>" and "</data>" texts inside
// a data section.
// Also take care not to use an escaped <data> (i.e. "~<data>") as the start
// of a data section. (Same for </data>)
// NOTE: we are explicitly searching for a data section that contains a JSON
// string, i.e. framed with braces. This way we are little bit more robust in
// case the tiddler contains unescaped texts "<data>" or "</data>". This must
// be changed when using a different stringifier.
var startTagText = "<data>{";
var endTagText = "}</data>";
var startPos = 0;
// Find the first not escaped "<data>".
var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
if (startDataTagIndex < 0) {
return null;
}
// Find the *last* not escaped "</data>".
var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
if (endDataTagIndex < 0) {
return null;
}
var nextEndDataTagIndex;
while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
endDataTagIndex = nextEndDataTagIndex;
}
return {
prefixEnd: startDataTagIndex,
dataStart: startDataTagIndex+(startTagText.length)-1,
dataEnd: endDataTagIndex,
suffixStart: endDataTagIndex+(endTagText.length)
};
};
// Internal.
//
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
var text = tiddler.text;
var info = DataTiddler.getDataSectionInfo(text);
if (!info) {
return null;
}
var prefix = text.substr(0,info.prefixEnd);
var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
var suffix = text.substr(info.suffixStart);
return [text, prefix, data, suffix];
};
// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change).
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected.
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send.
//
// This method should only be called when the data really has changed.
//
// @param tiddler
// the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
var prefix;
var suffix;
if (matches === null) {
prefix = tiddler.text;
suffix = "";
} else {
prefix = matches[1];
suffix = matches[3];
}
var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
var newText =
(dataText !== null)
? prefix + "<data>" + dataText + "</data>" + suffix
: prefix + suffix;
if (newText != tiddler.text) {
// make the change in the tiddlers text
// ... see DataTiddler.MyTiddlerChangedFunction
tiddler.isDataTiddlerChange = true;
// ... do the action change
tiddler.set(
tiddler.title,
newText,
config.options.txtUserName,
config.options.chkForceMinorUpdate? undefined : new Date(),
tiddler.tags);
// ... see DataTiddler.MyTiddlerChangedFunction
delete tiddler.isDataTiddlerChange;
// Mark the store as dirty.
store.dirty = true;
// AutoSave if option is selected
if(config.options.chkAutoSave) {
saveChanges();
}
}
};
// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
// Remove the data object from the tiddler when the tiddler is changed
// by code other than DataTiddler code.
//
// This is necessary since the data object is just a "cached version"
// of the data defined in the data section of the tiddler and the
// "external" change may have changed the content of the data section.
// Thus we are not sure if the data object reflects the data section
// contents.
//
// By deleting the data object we ensure that the data object is
// reconstructed the next time it is needed, with the data defined by
// the data section in the tiddler's text.
// To indicate that a change is a "DataTiddler change" a temporary
// property "isDataTiddlerChange" is added to the tiddler.
if (this.dataObject && !this.isDataTiddlerChange) {
delete this.dataObject;
}
// call the original code.
DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);
};
//============================================================================
// Formatters
//============================================================================
// This formatter ensures that "~<data>" is rendered as "<data>". This is used to
// escape the "<data>" of a data section, just in case someone really wants to use
// "<data>" as a text in a tiddler and not start a data section.
//
// Same for </data>.
//
config.formatters.push( {
name: "data-escape",
match: "~<\\/?data>",
handler: function(w) {
w.outputText(w.output,w.matchStart + 1,w.nextMatch);
}
} );
// This formatter ensures that <data>...</data> sections are not rendered.
//
config.formatters.push( {
name: "data",
match: "<data>",
handler: function(w) {
var info = DataTiddler.getDataSectionInfo(w.source);
if (info && info.prefixEnd == w.matchStart) {
w.nextMatch = info.suffixStart;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
} );
//============================================================================
// Tiddler Class Extension
//============================================================================
// "Hijack" the changed method ---------------------------------------------------
DataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;
Tiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;
// Define accessor methods -------------------------------------------------------
// Returns the value of the given data field of the tiddler. When no such field
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
return (field)
? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
: DataTiddler.getTiddlerDataObject(this);
};
// Sets the value of the given data field of the tiddler to the value. When the
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};
//============================================================================
// showData Macro
//============================================================================
config.macros.showData = {
// Standard Properties
label: "showData",
prompt: "Display the values stored in the data section of the tiddler"
};
config.macros.showData.handler = function(place,macroName,params) {
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the optional "JSON"
var showInJSONFormat = false;
if ((i < params.length) && params[i] == "JSON") {
i++;
showInJSONFormat = true;
}
var tiddlerName = story.findContainingTiddler(place).id.substr(7);
if (i < params.length) {
tiddlerName = params[i];
i++;
}
// --- Processing ------------------------------------------
try {
if (showInJSONFormat) {
this.renderDataInJSONFormat(place, tiddlerName);
} else {
this.renderDataAsTable(place, tiddlerName);
}
} catch (e) {
this.createErrorElement(place, e);
}
};
config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
var text = DataTiddler.getDataText(tiddlerName);
if (text) {
createTiddlyElement(place,"pre",null,null,text);
}
};
config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
var text = "|!Name|!Value|\n";
var data = DataTiddler.getDataObject(tiddlerName);
if (data) {
for (var i in data) {
var value = data[i];
text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
}
}
wikify(text, place);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.showData.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".showDataError{color: #ffffff;background-color: #880000;}",
"showData");
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... TiddlyWiki Core
/*global createTiddlyElement, saveChanges, store, story, wikify */
// ... DataTiddler
/*global DataTiddler */
// ... JSON
/*global JSON */
/***
!JSON Code, used to serialize the data
***/
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
The global object JSON contains two methods.
JSON.stringify(value) takes a JavaScript value and produces a JSON text.
The value must not be cyclical.
JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
throw a 'JSONError' exception if there is an error.
*/
var JSON = {
copyright: '(c)2005 JSON.org',
license: 'http://www.crockford.com/JSON/license.html',
/*
Stringify a JavaScript value, producing a JSON text.
*/
stringify: function (v) {
var a = [];
/*
Emit a string.
*/
function e(s) {
a[a.length] = s;
}
/*
Convert a value.
*/
function g(x) {
var c, i, l, v;
switch (typeof x) {
case 'object':
if (x) {
if (x instanceof Array) {
e('[');
l = a.length;
for (i = 0; i < x.length; i += 1) {
v = x[i];
if (typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(v);
}
}
e(']');
return;
} else if (typeof x.toString != 'undefined') {
e('{');
l = a.length;
for (i in x) {
v = x[i];
if (x.hasOwnProperty(i) &&
typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(i);
e(':');
g(v);
}
}
return e('}');
}
}
e('null');
return;
case 'number':
e(isFinite(x) ? +x : 'null');
return;
case 'string':
l = x.length;
e('"');
for (i = 0; i < l; i += 1) {
c = x.charAt(i);
if (c >= ' ') {
if (c == '\\' || c == '"') {
e('\\');
}
e(c);
} else {
switch (c) {
case '\b':
e('\\b');
break;
case '\f':
e('\\f');
break;
case '\n':
e('\\n');
break;
case '\r':
e('\\r');
break;
case '\t':
e('\\t');
break;
default:
c = c.charCodeAt();
e('\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16));
}
}
}
e('"');
return;
case 'boolean':
e(String(x));
return;
default:
e('null');
return;
}
}
g(v);
return a.join('');
},
/*
Parse a JSON text, producing a JavaScript value.
*/
parse: function (text) {
var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
token,
operator;
function error(m, t) {
throw {
name: 'JSONError',
message: m,
text: t || operator || token
};
}
function next(b) {
if (b && b != operator) {
error("Expected '" + b + "'");
}
if (text) {
var t = p.exec(text);
if (t) {
if (t[2]) {
token = null;
operator = t[2];
} else {
operator = null;
try {
token = eval(t[1]);
} catch (e) {
error("Bad token", t[1]);
}
}
text = text.substring(t[0].length);
} else {
error("Unrecognized token", text);
}
} else {
token = operator = undefined;
}
}
function val() {
var k, o;
switch (operator) {
case '{':
next('{');
o = {};
if (operator != '}') {
for (;;) {
if (operator || typeof token != 'string') {
error("Missing key");
}
k = token;
next();
next(':');
o[k] = val();
if (operator != ',') {
break;
}
next(',');
}
}
next('}');
return o;
case '[':
next('[');
o = [];
if (operator != ']') {
for (;;) {
o.push(val());
if (operator != ',') {
break;
}
next(',');
}
}
next(']');
return o;
default:
if (operator !== null) {
error("Missing value");
}
k = token;
next();
return k;
}
}
next();
return val();
}
};
/***
!Setup the data serialization
***/
DataTiddler.format = "JSON";
DataTiddler.stringify = JSON.stringify;
DataTiddler.parse = JSON.parse;
//}}}
/***
|''Name:''|Dictionary.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Localization tool for E-Math-book|
|''Version:''|1.0|
|''Date:''|November 2, 2012|
|''Source:''||
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130830.1258 ''add''
* showDictData-macro to show data as a table in ebdictset-tiddler
<<<
!!!!!TODO
<<<
* Remove terms from this tiddler. They are in separate tiddlers.
<<<
!!!!!Code
***/
//{{{
var EbookDictionary = {
"assignmentTexture": {
"fi":"Tehtävä",
"sv":"Uppgift",
"en":"Assignment",
"et":"Ülesanne"
},
"basicAssignmentText": {
"fi":"Perustehtävät",
"sv":"Grunduppgifter",
"en":"Basic assignments",
"et":"Lähteülesanded"
},
"examplebox": {
"fi":"Esimerkki",
"sv":"Exempel",
"en":"Example",
"et":"Näide"
},
"example": {
"fi":"Esimerkki",
"sv":"Exempel",
"en":"Example",
"et":"Näide"
},
"theorybox": {
"fi":"Teoria",
"sv":"Teori",
"en":"Theory",
"et":"Teooria"
},
"theory": {
"fi":"Teoria",
"sv":"Teori",
"en":"Theory",
"et":"Teooria"
},
"derivation": {
"fi":"päättelyketju",
"sv":"härledning",
"en":"derivation",
"et":"lahenduskäik"
},
"text": {
"fi":"teksti",
"sv":"text",
"en":"text",
"et":"tekst"
},
"wikitext": {
"fi":"wikiteksti",
"sv":"wikitext",
"en":"wikitext",
"et":"wikitekst"
},
"table": {
"fi":"taulukko",
"sv":"tabell",
"en":"table",
"et":"tabel"
},
"funcgraph": {
"fi":"kuvaaja",
"sv":"graf",
"en":"graph",
"et":"graafik"
},
"signchart": {
"fi":"merkkikaavio",
"sv":"signchart",
"en":"signchart",
"et":"signchart"
},
// Highlight tool
"invalid selection": {
"fi":"Valitan. Tätä valintaa ei voi käyttää.",
"sv":"Tyvärr. Den här markeringen kan inte användas.",
"en":"Can not use this selection.\nSorry.",
"et":"Vabandust. Seda valikut ei saa kasutada."
},
"set comment tool on first": {
"fi":"Kommentointityökalu pitää olla päällä, jotta voit käyttää tätä toimintoa.",
"sv":"För att använda denna funktion måste kommenteringsverktyget vara på.",
"en":"To use this function, you need to have comment tool on.",
"et":"Selle funktsiooni kasutamiseks peab kommenteerimise tööriist olema sisse lülitatud." // Localize
},
// Author tools
"youre translating":{
"fi":"Olet kääntämässä aineistoa kielestä %0 kieleen %1.",
"sv":"Du håller på att översätta material från språk %0 till språk %1.",
"en":"You are translating material from language %0 to language %1.",
"et":"Sa tõlgit materjali keelest %0 keelde %1."
},
// Teacher tools
"ADD":{
"fi":"Lisää...",
"sv":"Lägg till...",
"en":"Add...",
"et":"Lisa..."
},
"Home assignments":{
"fi":"Merkitse kotitehtävät",
"sv":"Markera hemuppgifterna",
"en":"Mark home assignments",
"et":"Märgi kodused ülesanded"
},
"Check solutions":{
"fi":"Nouda opiskelijoiden ratkaisut",
"sv":"Hämta studerandenas lösningar",
"en":"Get students' solutions",
"et":"Kogu kokku õpilaste lahendused"
},
"Student management":{
"fi":"Opiskelijoiden hallinta",
"sv":"Förvaltning av studerandena",
"en":"Student management",
"et":"Õpilaste haldamine"
},
"Return to teacher view":{
"fi":"Palaa opettajan näkymään",
"sv":"Gå tillbaka till lärarens vy",
"en":"Return to teacher's view",
"et":"Tagasi õpetaja rollile"
},
"show student view":{
"fi":"Siirry opiskelijan näkymään",
"sv":"GÃ¥ till studentens vy",
"en":"Change to student's view",
"et":"Lülitu õpilase rollile"
},
"only on assignment page": {
"en": "These can be added only on assignment pages.",
"fi": "Voidaan lisätä vain tehtäväsivuille.",
},
"no assignments": {
"en": "No assignments on this page.",
"fi": "Tällä sivulla ei ole tehtäviä.",
},
"Teachers": {
"en": "Teacher's:",
"fi": "Opettajan lisäämät:",
},
"model from student": {
"en": "Make a modelsolution from this student's solution.",
"fi": "Tee tästä oppilaan ratkaisusta malliratkaisu.",
},
"edit teacherelement": {
"en": "Edit this teacher's element.",
"fi": "Muokkaa opettajan lisäämää elementtiä.",
},
"delete teacherelement": {
"en": "Delete this teacher's element.",
"fi": "Poista tämä opettajan lisäämä elementti.",
},
"teachers types": {
"en": "Change the type",
"fi": "Vaihda tyyppiä",
},
"edit homeassignments": {
"en": "Edit homeassignments:",
"fi": "Muokkaa kotitehtäviä:",
},
"new homeassignments": {
"en": "Mark new homeassignments",
"fi": "Merkitse uusia kotitehtäviä",
},
"Evaluate": {
"en": "Evaluate",
"fi": "Arvioi",
},
"Modelsolution": {
"en": "Make modelsolution",
"fi": "Malliratkaisuksi",
},
"homeassignment title": {
"en": "Title of homeassignment",
"fi": "Kotitehtävien otsikko"
},
"homeassignments": {
"en": "Homeassignments",
"fi": "Kotitehtävät"
},
"own bookmarks": {
"en": "Own bookmarks",
"fi": "Omat kirjanmerkit"
},
"assignment": {
"en": "Assignment",
"fi": "Tehtävä"
},
"plainText": {
"en": "Plain text",
"fi": "Pelkkää tekstiä"
},
"multichoise": {
"en": "Multichoise quiz",
"fi": "Monivalintatehtävä"
},
"shortanswer": {
"en": "Shortanswer",
"fi": "Lyhytsyöttötehtävä"
},
"SDshuffle": {
"en": "Shuffled structured derivation",
"fi": "Sekoitettu päättelyketju"
},
"Add incorrect": {
"en": "Add incorrect answer",
"fi": "Lisää väärä vastausvaihtoehto"
},
// System translations
"about to update": {
"fi":"Aiot päivittää kirjan.\nOletko varma?",
"sv":"Är du säker på att du vill uppdatera boken?",
"en":"About to update.\nAre you sure?",
"et":"Kavatsed uuendada.\nOled sa kindel?"
},
"no updates available": {
"fi":"Ei päivityksiä saatavilla kirjaan: ",
"sv":"Inga uppdateringar till boken är tillgängliga: ",
"en":"No updates available for book: ",
"et":"Uuendusi pole saadaval raamatusse: "
},
"updates ready": {
"fi":"Päivitykset ovat valmiit.\n%0 päivitystä tehty.",
"sv":"Uppdateringarna är färdiga.\n%0 uppdateringar gjordes.",
"en":"Updates are ready.\n%0 updates done.",
"et":"Uuendused on valmis.\nTehtud %0 uuendust."
},
"system updates ready": {
"fi":"Järjestelmäpäivitykset ovat valmiit.\n%0 päivitystä tehty.",
"sv":"Systemuppdateringarna är färdiga.\n%0 uppdateringar gjordes.",
"en":"System updates are ready.\n%0 updates done.",
"et":"Süsteemiuuendused on valmis.\n%0 uuendust tehtud."
},
"system updates done": {
"fi":"Järjestelmäpäivitykset ovat valmiit. Selain latautuu uudelleen automaattisesti.",
"sv":"Systemuppdateringarna är färdiga. Webbläsaren kommer att uppdateras automatiskt.",
"en":"System updates are ready. The browser will refresh automatically.",
"et":"Süsteemiuuendused on valmis. Brauser uuendab lehe automaatselt."
},
"give feedback": {
"fi":"Anna palautetta",
"sv":"Ge respons",
"en":"Give feedback",
"et":"Anna tagasisidet"
},
"Check courseupdates": {
"fi":"Päivitä kurssin tiedot",
"sv":"Updatera kursinformationen.",
"en":"Update course information.",
"et":"Uuenda kursuse infot."
},
"checking contentupdates": {
"fi":"Haetaan sisältöpäivityksiä.",
"sv":"Boken hämtar uppdateringar till innehållet.",
"en":"Getting content updates.",
"et":"Kontrollitakse sisu uuendusi."
},
"no internetconnection": {
"fi":"Ei yhteyttä palvelimeen. Yritä myöhemmin uudelleen.",
"sv":"Ingen kontakt till servern. Försök igen senare.",
"en":"No connection to server. Try again later.",
"et":"Ühendus serveriga puudub. Proovi hiljem uuesti."
},
"contentupdates done": {
"fi":"Sisältöpäivitykset valmiit.",
"sv":"Uppdateringarna är färdiga.",
"en":"Content updates are ready.",
"et":"Uuendused on valmis."
},
"comments ready": {
"fi":"%0 sivukommenttia kirjoihin: %1.",
"sv":"%0 kommentarer till böckerna: %1.",
"en":"%0 page comments to books: %1.",
"et":"%0 kommentaari raamatutele: %1."
},
"username": {
"fi":"Käyttäjänimi",
"sv":"Användarnamn",
"en":"Username",
"et":"Kasutajanimi"
},
"give a valid username": {
"fi":"Anna kelvollinen käyttäjänimi!\nYritit nimeä: %0",
"sv":"Ge ett giltigt användarnamn!\nDu gav: %0",
"en":"Give a valid username!\nYou gave: %0",
"et":"Palun sisesta kehtiv kasutajanimi! Sa proovisid nime: %0"
},
"show userkey": {
"fi":"Näytä käyttäjäavain",
"sv":"Visa användarnyckel",
"en":"Show userkey",
"et":"Näita kasutajavõtit"
},
"invalid user": {
"fi":"Käyttäjätiedot väärin.",
"sv":"Felaktig användarinformation. ",
"en":"Incorrect user information.",
"et":"Vigased kasutaja andmed."
},
"connection error": {
"fi":"Virhe verkkoyhteydessä.",
"sv":"Fel i nätverksanslutningen.",
"en":"Error in network connection.",
"et":"Viga võrguühenduses."
},
"give all information": {
"fi":"Täytä kaikki kohdat.",
"sv":"Fyll i all information.",
"en":"Fill all information.",
"et":"Täida kõik andmed."
},
"give username": {
"fi":"Anna käyttäjänimesi",
"sv":"Ange ditt användarnamn",
"en":"Give your username",
"et":"Anna kasutajanimi"
},
"courseid": {
"fi":"Kurssin tunnus",
"sv":"Kurs ID",
"en":"Course id",
"et":"Kursuse ID"
},
"userkey": {
"fi":"Käyttäjäavain",
"sv":"Användarnyckel",
"en":"Userkey",
"et":"Kasutajavõti"
},
"give userdata": {
"fi":"Anna tietosi",
"sv":"Ge din information",
"en":"Give your information",
"et":"Sisesta oma andmed"
},
"available characters": {
"fi":"Käytettävissä olevat merkit",
"sv":"Tillgängliga tecken",
"en":"Available characters",
"et":"Saadaolevad märgid"
},
"Ebook Settings": {
"fi":"E-kirjan asetukset",
"sv":"E-bokens inställningar",
"en":"Ebook Settings",
"et":"E-raamatu seaded"
},
"Settings": {
"fi":"Asetukset",
"sv":"Inställningar",
"en":"Settings",
"et":"Seaded"
},
"Choose the theme": {
"fi":"Teema:",
"sv":"Tema:",
"en":"Theme:",
"et":"Teema:"
},
"Choose the language": {
"fi":"Kieli:",
"sv":"Språk:",
"en":"Language:",
"et":"Keel:"
},
"textbooks": {
"fi":"Oppikirjat",
"sv":"Läroböcker",
"en":"Textbooks",
"et":"Õpikud"
},
"byebye": {
"fi":"Moi, moi!",
"sv":"Hejdå!",
"en":"Bye, bye!",
"et":"Kohtumiseni!"
},
"editsolution": {
"fi":"Muokkaa",
"sv":"Redigera",
"en":"Edit",
"et":"Muuda"
},
"edit": {
"fi":"Muokkaa",
"sv":"Redigera",
"en":"Edit",
"et":"Muuda"
},
"areyousure": {
"fi":"Oletko varma?",
"sv":"Är du säker?",
"en":"Are you sure?",
"et":"Kas sa oled kindel?"
},
"answer": {
"fi":"Vastaus: ",
"sv":"Svar: ",
"en":"Answer: ",
"et":"Vastus: "
},
"Make solution": {
"fi":"Ratkaise",
"sv":"Lös",
"en":"Solve",
"et":"Lahenda"
},
"can not copy": {
"fi":"Ei voida kopioida seuraavaa:",
"sv":"Det följande går inte att kopiera:",
"en":"Can not copy following:",
"et":"Ei saa järgnevat kopeerida:"
},
"not yet translated": {
"fi":"Tämä osio ei ole vielä käännetty.",
"sv":"Denna del har inte ännu blivit översatt.",
"en":"This part has not yet been translated.",
"et":"See osa on veel tõlkimata."
},
"order": {
"fi":"Järjestä",
"sv":"Ordna",
"en":"Order",
"et":"Sorteeri"
},
"ready": {
"fi":"Valmis",
"sv":"Färdig",
"en":"Ready",
"et":"Valmis"
},
"cancel": {
"fi":"Peruuta",
"sv":"Avbryt",
"en":"Cancel",
"et":"Tühista"
},
"close": {
"fi":"Sulje",
"sv":"Stäng",
"en":"Close",
"et":"Sulge"
},
"Close book": {
"fi":"Sulje kirja",
"sv":"Stäng boken",
"en":"Close book",
"et":"Sulge raamat"
},
"Open book": {
"fi":"Avaa kirja",
"sv":"Öppna boken",
"en":"Open book",
"et":"Ava raamat"
},
"Book is closed": {
"fi":"Kirja on nyt suljettu",
"sv":"Boken har stängts",
"en":"Book is now closed",
"et":"Raamat on suletud"
},
"Saving and closing": {
"fi":"Talletetaan ja suljetaan kirjaa.",
"sv":"Sparar och stänger boken.",
"en":"Saving and closing.",
"et":"Salvestatakse ja suletakse raamatut."
},
"publish": {
"fi":"Julkaise",
"sv":"Publicera",
"en":"Publish",
"et":"Avalda"
},
"Loading book": {
"fi":"Ladataan kirjaa",
"sv":"Boken håller på att laddas",
"en":"Loading book",
"et":"Raamatut laetakse"
},
"Loading...": {
"fi":"Ladataan...",
"sv":"Laddas...",
"en":"Loading...",
"et":"Laetakse..."
},
"Getting systemupdates": {
"fi":"Haetaan järjestelmäpäivityksiä",
"sv":"Håller på att hämta systemuppdateringar",
"en":"Getting system updates",
"et":"Kontrollitakse süsteemi uuendusi"
},
"comment this page": {
"fi": "Kommentoi tätä sivua",
"en": "Comment this page",
"sv": "Kommentera denna sida",
"et": "Comment this page"
},
"comment type": {
"fi": "Kommentin tyyppi",
"en": "Comment type",
"sv": "Typen av kommentaren",
"et": "Kommentaari liik"
},
"general": {
"fi": "Yleinen",
"en": "General",
"sv": "Generell",
"et": "Üldine"
},
"content": {
"fi": "Sisältö",
"en": "Content",
"sv": "Innehåll",
"et": "Sisu"
},
"system": {
"fi": "Järjestelmä",
"en": "System",
"sv": "System",
"et": "Süsteem"
},
"layout": {
"fi": "Ulkoasu",
"en": "Layout",
"sv": "Layout",
"et": "Paigutus"
},
"my comment": {
"fi": "Kommenttini",
"en": "My comment",
"sv": "Min kommentar",
"et": "Minu kommentaar"
},
//Preview DICTIONARY
"previewbook": {
"fi":"Valitse kirja.",
"sv":"Välj en bok.",
"en":"Choose the book.",
"et":"Vali raamat."
},
"give a valid previewname": {
"fi":"Jotain meni väärin. Yritä uudelleen.",
"sv":"Något gick fel. Försök igen.",
"en":"Something went wrong. Try again.",
"et":"Midagi läks valesti. Proovi uuesti."
},
//COURSE MANAGEMENT DICTIONARY
"course students": {
"fi":"Kurssin oppilaat",
"sv":"Elever på kursen",
"en":"Course students",
"et":"Kursusel osalejad"
},
"student textarea info": {
"fi":"Voit listata tekstikenttään kurssiin lisättävät opiskelijat allekkain muodossa etunimi;sukunimi;sähköposti (esim. tero;testisukunimi;tertes@testi.fi)",
"sv":"I textfältet kan du radvis lista de elever som ska registreras på kursen. Använd följande format för vardera elev: förnamn;efternamn;e-post (t.ex. anders;andersson;andersandersson@exempel.se",
"en":"You can list the students one per row in following format: firstname;lastname;email (ie. john;doe;johndoe@example.com)",
"et":"Kursusel osalejatest saab teha nimekirja paigutades iga osaleja omaette reale järgmiselt: eesnimi;perekonnanimi;e-mail (nt matias;maru;matias.maru@naide.ee)"
},
"add course students": {
"fi":"Lisää oppilaita kurssiin",
"sv":"Lägg till elever till kursen",
"en":"Add students to this course",
"et":"Lisa kursusele osalejaid"
},
"add course students from textarea": {
"fi":"Lisää oppilaita kurssiin tekstikentästä",
"sv":"Lägg till elever till kursen från textfältet",
"en":"Add students to this course from textarea",
"et":"Lisa kursusele osalejaid tekstirealt"
},
"student": {
"fi":"oppilas",
"sv":"elev",
"en":"student",
"et":"õpilane"
},
"fname": {
"fi":"etunimi",
"sv":"förnamn",
"en":"first name",
"et":"eesnimi"
},
"lname": {
"fi":"sukunimi",
"sv":"efternamn",
"en":"last name",
"et":"perekonnanimi"
},
"userid": {
"fi":"tunnus",
"sv":"användarnamn",
"en":"userid",
"et":"kasutajatunnus"
},
"email": {
"fi":"sähköposti",
"sv":"e-post",
"en":"email",
"et":"e-post"
},
"gender": {
"fi":"sukupuoli",
"sv":"kön",
"en":"gender",
"et":"sugu"
},
"course": {
"fi": "kurssi",
"sv": "kurs",
"en": "course",
"et": "kursus"
},
"add": {
"fi":"Lisää",
"sv":"Lägg till",
"en":"Add",
"et":"Lisa"
},
"send": {
"fi":"Lähetä",
"sv":"Skicka",
"en":"Send",
"et":"Saada"
},
"save": {
"fi":"Tallenna",
"sv":"Spara",
"en":"Save",
"et":"Salvesta"
},
"save to server": {
"fi":"siirrä palvelimelle",
"sv":"skicka till servern",
"en":"save to server",
"et":"salvesta serverisse"
},
"update from server": {
"fi":"päivitä palvelimelta",
"sv":"uppdatera från servern",
"en":"update from server",
"et":"uuenda serverist"
},
"return students from server": {
"fi":"Palauta palvelimelta",
"sv":"Återställ från servern",
"en":"Restore from backups",
"et":"Taasta varukoopiast"
},
"delete": {
"fi":"Poista",
"sv":"Radera",
"en":"Delete",
"et":"Kustuta"
},
"print": {
"fi":"Tulosta",
"sv":"Skriv ut",
"en":"Print",
"et":"Prindi"
},
"choose": {
"fi":"Valitse",
"sv":"Välj",
"en":"Choose",
"et":"Vali"
},
"boy": {
"fi":"poika",
"sv":"pojke",
"en":"boy",
"et":"poiss"
},
"girl": {
"fi":"tyttö",
"sv":"flicka",
"en":"girl",
"et":"tüdruk"
},
"empty lname": {
"fi":"Sukunimi ei saa olla tyhjä!",
"sv":"Efternamn får inte vara tomt",
"en":"Lastname cannot be empty!",
"et":"Perekonnanimi ei tohi olla tühi!"
},
"empty fname": {
"fi":"Etunimi ei saa olla tyhjä!",
"sv":"Förnamn får inte vara tomt",
"en":"First name cannot be empty!",
"et":"Eesnimi ei tohi olla tühi!"
},
"invalid email": {
"fi":"Sähköpostiosoite ei ole oikeassa muodossa!",
"sv":"E-post adressen är felaktig",
"en":"Invalid email adress!",
"et":"Vigane e-posti aadress"
},
"empty lname and row": {
"fi":"Sukunimi ei saa olla tyhjä rivillä ",
"sv":"Efternamnet får inte vara tomt på raden",
"en":"Lastname cannot be empty on row ",
"et":"Perekonnanimi ei tohi olla tühi rida"
},
"empty fname and row": {
"fi":"Etunimi ei saa olla tyhjä rivillä ",
"sv":"Förnamnet får inte vara tomt på raden",
"en":"Firstname cannot be empty on row ",
"et":"Eesnimi ei tohi olla tühi rida"
},
"invalid email and row": {
"fi":"Sähköpostiosoite ei ole oikeassa muodossa rivillä ",
"sv":"E-post adressen är felaktig på raden",
"en":"Invalid email adress on row ",
"et":"E-posti aadress on reas vigane"
},
"invalid text format on row": {
"fi": "Teksti ei ole oikeassa muodossa rivillä ",
"sv":"Texten är felaktig på raden",
"en":"Invalid text format on row ",
"et":"Tekst on reas vigane"
},
"cannot save students": {
"fi": "Etunimet ja sukunimet eivät saa olla tyhjiä ja jokaisen sähköpostiosoitteen pitää olla joko tyhjä tai oikeassa muodossa. Oppilaita ei voitu tallentaa.",
"sv":"Förnamn och efternamn får inte vara tomma och varje e-post adress måste vara antingen tom eller skriven i rätt format. Eleverna kunde inte sparas.",
"en":"Firstnames and lastnames cannot be empty and the emails have to be either empty or be valid. The students could not be saved.",
"et":"Eesnimed ja perekonnanimed ei tohi olla tühjad ning e-postid peavad olema tühjad või kehtivad. Osalejaid ei saanud salvestada."
},
"cannot save textarea": {
"fi": "Tekstitkenttä sisältää virheitä ja siksi siinä olevia oppilaita ei voitu tallentaa. Poista virheet ja tallenna uudelleen!",
"sv":"Textfältet innehåller fel och därför kunde eleverna inte sparas. Korrigera felen och spara på nytt!",
"en":"There are errors in the textarea and the students could not be saved. Fix the errors and save again!",
"et":"Tekstiread on vigased ning seeõttu ei saanud osalejaid salvestada. Paranda vead ning salvesta uuesti!"
},
"delete student": {
"fi": "Haluatko varmasti poistaa tämän oppilaan oppilaslistasta?",
"sv":"Är du säker på att du vill radera denna elev från listan?",
"en":"Delete this student from course student list?",
"et":"Oled kindel, et soovid selle õpilase osalejate nimekirjast kustutada?"
},
"editable tooltip": {
"fi": "klikkaamalla tähän pääset muokkaustilaan...",
"sv":"klicka här för att redigera...",
"en":"click here to edit...",
"et":"vajuta muutmiseks siia..."
},
"input empty": {
"fi": "Tekstilaatikko ei saa olla tyhjä!",
"sv":"Textfältet får inte vara tomt!",
"en":"Input box cannot be empty!",
"et":"Tekstiväli ei tohi olla tühi!"
},
"students textarea hint": {
"fi": "joona;lehtinen;jole@esimerkki.fi saara;laaksonen;sala@esimerkki.fi heikki;heikkinen;hehheh@esimerkki.fi",
"sv":"anders;andersson;andersandersson@exempel.se emma;exempel;emma.exempel@exempel.se håkan;håkansson;haha@exempel.se",
"en":"johnny;doe;johnny.doe@example.com janette;doe;janette.doe@example.com.fi earl;example;earl.example@example.com",
"et":"kati;karu;kati.karu@naide.ee matias;maru;matias.maru@naide.ee tiina;kask;tiina.kask@naide.ee"
},
"save unsuccessful get from server": {
"fi": "Tallennus epäonnistui! Päivitä ensin kurssin tiedot palvelimelta ja tallenna uudelleen.",
"sv":"Sparandet misslyckades! Uppdatera först kursinformation från servern och spara sedan på nytt.",
"en":"Save unsuccessful! Update course data from server first and save again.",
"et":"Salvestamine ebaõnnestus! Uuenda serverist kursuse andmeid ning proovi seejärel uuesti."
},
"save successful": {
"fi": "Tallennus onnistui!",
"sv":"Sparandet lyckades!",
"en":"Save successful!",
"et":"Salvestamine õnnestus!"
},
"students without gender": {
"fi": "Tallennus epäonnistui! Valitse sukupuoli jokaiselle oppilaalle.",
"sv":"Sparandet misslyckades! Välj kön för varje elev.",
"en":"Save unsuccessful! Choose a gender for every student",
"et":"Salvestamine ebaõnnestus! Vali iga õpilase sugu."
},
"password": {
"fi": "salasana",
"sv":"lösenord",
"en":"password",
"et":"salasõna"
},
"sProcessing":{
"fi": "Hetkinen...",
"sv": "Laddar...",
"en": "Processing...",
"et": "Üks hetk..."
},
"sLengthMenu":{
"fi": "Näytä kerralla _MENU_ riviä",
"sv": "Visa _MENU_ rader",
"en": "Show _MENU_ entries",
"et": "Kuva _MENU_ kirjet"
},
"sZeroRecords":{
"fi": "Tietoja ei löytynyt",
"sv": "Inga matchande resultat funna",
"en": "No matching records found",
"et": "Otsitavat vastet ei leitud."
},
"sInfo":{
"fi": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )",
"sv": "Visar _START_ till _END_ av totalt _TOTAL_ rader",
"en": "Showing _START_ to _END_ of _TOTAL_ entries",
"et": "Kuvatakse _START_ - _END_ kirjet _TOTAL_ kirjest"
},
"sInfoEmpty":{
"fi": "Näytetään 0 - 0 (yhteensä 0)",
"sv": "Visar 0 till 0 av totalt 0 rader",
"en": "Showing 0 to 0 of 0 entries",
"et": "Kuvamiseks pole ühtegi kirjet"
},
"sInfoFiltered":{
"fi": "(suodatettu _MAX_ tuloksen joukosta)",
"sv": "(filtrerade från totalt _MAX_ rader)",
"en": "(filtered from _MAX_ total entries)",
"et": "(filtreeritud _MAX_ kirje seast)"
},
"sSearch":{
"fi": "Etsi:",
"sv": "Sök:",
"en": "Search:",
"et": "Otsi:"
},
"sFirst":{
"fi": "Ensimmäinen",
"sv": "Första",
"en": "First",
"et": "Esimene"
},
"sPrevious":{
"fi": "Edellinen",
"sv": "Föregående",
"en": "Previous",
"et": "Eelmine"
},
"sNext":{
"fi": "Seuraava",
"sv": "Nästa",
"en": "Next",
"et": "Järgmine"
},
"sLast":{
"fi": "Viimeinen",
"sv": "Sista",
"en": "Last",
"et": "Viimane"
},
"tablefill":{
"fi": "Täytä taulukko",
"sv": "Fyll i tabellen",
"en": "Fill table",
"et": "Täida table"
},
"fillsd":{
"fi": "Täytä päättelyketju",
"sv": "Fyll i härledningen",
"en": "Fill derivation",
"et": "Täida lahenduskäik"
},
"ordersd":{
"fi": "Järjestä päättelyketju",
"sv": "Ordna härledningen",
"en": "Order derivation",
"et": "Korrasta lahenduskäik"
},
"openemathcenter":{
"fi": "Avaa E-mathcenter",
"sv": "Öppna E-mathcenter",
"en": "Open E-mathcenter",
"et": "Ava E-mathcenter"
},
"Show mqpanel": {
"fi":"Näytä matikkapaneli",
"sv":"Visa matematikpanelen",
"en":"Show mathpanel",
"et":"Näita matemaatikapaneel"
},
"Hide mqpanel": {
"fi":"Piilota matikkapaneli",
"sv":"Göm matematikpanelen",
"en":"Hide mathpanel",
"et":"Peida matemaatikapaneel"
},
"markings": {
"fi":"Merkinnät",
"sv":"Markeringarna",
"en":"Markings",
"et":"Märgistus"
},
"preview": {
"fi":"Esikatselu",
"sv":"Förhandsgranskning",
"en":"Preview",
"et":"Eelvaade"
},
"Calculator": {
"fi":"Laskin",
"sv":"Räknare",
"en":"Calculator",
"et":"Kalkulaator"
},
"presentation view open": {
"fi":"Esitystila",
"en":"Presentation mode"
},
"course chat": {
"fi":"Kurssi-chat",
"en":"Course chat"
},
"please install plugin": {
"fi": "Ole hyvä ja asenna E-math-plugin.",
"en": "Please, install E-math-plugin."
},
"click here": {
"fi": "Paina tästä",
"en": "Click here"
},
"Comments on page": {
"fi":"Sivuun liittyvät kommentit",
"sv":"Comments on page",
"en":"Comments on page",
"et":"Comments on page"
},
"show": {
"fi":"näytä",
"sv":"visa",
"en":"show",
"et":"näita"
},
"hide": {
"fi":"piilota",
"sv":"dölja",
"en":"hide",
"et":"varjama"
},
"Hide hidden": {
"fi":"Poista piiloitetut",
"sv":"Hide hidden",
"en":"Hide hidden",
"et":"Hide hidden"
},
"Show hidden": {
"fi":"Näytä piiloitetut",
"sv":"Show hidden",
"en":"Show hidden",
"et":"Show hidden"
}
}
EbookDictionary.localize = function(keystring, page){
// Translate keystring to current language.
if (typeof page == 'number' && Emathbook.options.pages[page]){
var lang = Emathbook.options.pages[page].lang;
} else if (typeof page === 'string') {
var lang = page;
} else {
var lang = config.options.txtLang;
}
return (EbookDictionary[keystring] && (EbookDictionary[keystring][lang] || EbookDictionary[keystring]['en'])) || '[Missing localized string: '+keystring+']';
}
var EbookDictionary = {
terms: {}
};
EbookDictionary.init = function(){
// Init the dictionary from tiddlers tagged with ebdictset.
var dictsets = store.getTaggedTiddlers('ebdictset');
for (var i = 0; i < dictsets.length; i++) {
var data = dictsets[i].data('ebdict', {});
jQuery.extend(true, this.terms, data);
}
}
EbookDictionary.localize = function(keystring, page){
// Translate keystring to current language.
var uilang = config.options.txtLang;
if (typeof page == 'number' && Emathbook.options.pages[page]){
var lang = Emathbook.options.pages[page].lang;
} else if (typeof page === 'string') {
var lang = page;
} else {
var lang = uilang;
}
return (EbookDictionary.terms[keystring] && (EbookDictionary.terms[keystring][lang] || EbookDictionary.terms[keystring][uilang] || EbookDictionary.terms[keystring]['en'])) || '[Missing localized string: '+keystring+']';
}
EbookDictionary.init();
config.macros.showDictData = {
// Show Dictionary-data in table
handler: function(place, macroName, params, wikifier, paramString, tiddler){
var category = DataTiddler.getData(tiddler, 'dictname', '');
var data = DataTiddler.getData(tiddler, 'ebdict', {});
var text = '!'+category + '\n';
text += '|!Term|!Translations|\n';
if (data) {
for (var key in data) {
var value = data[key];
text += '|' + key + '|<html><dl>';
for (var trlang in value) {
text += '<dt>'+trlang+':</dt><dd>' + JSON.stringify(value[trlang]) + '</dd>';
}
text += '</dl></html>|\n';
}
}
wikify(text, place);
}
}
//}}}
/***
|Name|DisableWikiLinksPlugin|
|Source|http://www.TiddlyTools.com/#DisableWikiLinksPlugin|
|Version|1.6.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|selectively disable TiddlyWiki's automatic ~WikiWord linking behavior|
This plugin allows you to disable TiddlyWiki's automatic ~WikiWord linking behavior, so that WikiWords embedded in tiddler content will be rendered as regular text, instead of being automatically converted to tiddler links. To create a tiddler link when automatic linking is disabled, you must enclose the link text within {{{[[...]]}}}.
!!!!!Usage
<<<
You can block automatic WikiWord linking behavior for any specific tiddler by ''tagging it with<<tag excludeWikiWords>>'' (see configuration below) or, check a plugin option to disable automatic WikiWord links to non-existing tiddler titles, while still linking WikiWords that correspond to existing tiddlers titles or shadow tiddler titles. You can also block specific selected WikiWords from being automatically linked by listing them in [[DisableWikiLinksList]] (see configuration below), separated by whitespace. This tiddler is optional and, when present, causes the listed words to always be excluded, even if automatic linking of other WikiWords is being permitted.
Note: WikiWords contained in default ''shadow'' tiddlers will be automatically linked unless you select an additional checkbox option lets you disable these automatic links as well, though this is not recommended, since it can make it more difficult to access some TiddlyWiki standard default content (such as AdvancedOptions or SideBarTabs)
<<<
!!!!!Configuration
<<<
<<option chkDisableWikiLinks>> Disable ALL automatic WikiWord tiddler links
<<option chkAllowLinksFromShadowTiddlers>> ... except for WikiWords //contained in// shadow tiddlers
<<option chkDisableNonExistingWikiLinks>> Disable automatic WikiWord links for non-existing tiddlers
Disable automatic WikiWord links for words listed in: <<option txtDisableWikiLinksList>>
Disable automatic WikiWord links for tiddlers tagged with: <<option txtDisableWikiLinksTag>>
<<<
!!!!!Revisions
<<<
2008.07.22 [1.6.0] hijack tiddler changed() method to filter disabled wiki words from internal links[] array (so they won't appear in the missing tiddlers list)
2007.06.09 [1.5.0] added configurable txtDisableWikiLinksTag (default value: "excludeWikiWords") to allows selective disabling of automatic WikiWord links for any tiddler tagged with that value.
2006.12.31 [1.4.0] in formatter, test for chkDisableNonExistingWikiLinks
2006.12.09 [1.3.0] in formatter, test for excluded wiki words specified in DisableWikiLinksList
2006.12.09 [1.2.2] fix logic in autoLinkWikiWords() (was allowing links TO shadow tiddlers, even when chkDisableWikiLinks is TRUE).
2006.12.09 [1.2.1] revised logic for handling links in shadow content
2006.12.08 [1.2.0] added hijack of Tiddler.prototype.autoLinkWikiWords so regular (non-bracketed) WikiWords won't be added to the missing list
2006.05.24 [1.1.0] added option to NOT bypass automatic wikiword links when displaying default shadow content (default is to auto-link shadow content)
2006.02.05 [1.0.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.09 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.DisableWikiLinksPlugin= {major: 1, minor: 6, revision: 0, date: new Date(2008,7,22)};
if (config.options.chkDisableNonExistingWikiLinks==undefined) config.options.chkDisableNonExistingWikiLinks= false;
if (config.options.chkDisableWikiLinks==undefined) config.options.chkDisableWikiLinks=false;
if (config.options.txtDisableWikiLinksList==undefined) config.options.txtDisableWikiLinksList="DisableWikiLinksList";
if (config.options.chkAllowLinksFromShadowTiddlers==undefined) config.options.chkAllowLinksFromShadowTiddlers=true;
if (config.options.txtDisableWikiLinksTag==undefined) config.options.txtDisableWikiLinksTag="excludeWikiWords";
// find the formatter for wikiLink and replace handler with 'pass-thru' rendering
initDisableWikiLinksFormatter();
function initDisableWikiLinksFormatter() {
for (var i=0; i<config.formatters.length && config.formatters[i].name!="wikiLink"; i++);
config.formatters[i].coreHandler=config.formatters[i].handler;
config.formatters[i].handler=function(w) {
// supress any leading "~" (if present)
var skip=(w.matchText.substr(0,1)==config.textPrimitives.unWikiLink)?1:0;
var title=w.matchText.substr(skip);
var exists=store.tiddlerExists(title);
var inShadow=w.tiddler && store.isShadowTiddler(w.tiddler.title);
// check for excluded Tiddler
if (w.tiddler && w.tiddler.isTagged(config.options.txtDisableWikiLinksTag))
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// check for specific excluded wiki words
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList);
if (t && t.length && t.indexOf(w.matchText)!=-1)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not disabling links from shadows (default setting)
if (config.options.chkAllowLinksFromShadowTiddlers && inShadow)
return this.coreHandler(w);
// check for non-existing non-shadow tiddler
if (config.options.chkDisableNonExistingWikiLinks && !exists)
{ w.outputText(w.output,w.matchStart+skip,w.nextMatch); return; }
// if not enabled, just do standard WikiWord link formatting
if (!config.options.chkDisableWikiLinks)
return this.coreHandler(w);
// just return text without linking
w.outputText(w.output,w.matchStart+skip,w.nextMatch)
}
}
Tiddler.prototype.coreAutoLinkWikiWords = Tiddler.prototype.autoLinkWikiWords;
Tiddler.prototype.autoLinkWikiWords = function()
{
// if all automatic links are not disabled, just return results from core function
if (!config.options.chkDisableWikiLinks)
return this.coreAutoLinkWikiWords.apply(this,arguments);
return false;
}
Tiddler.prototype.disableWikiLinks_changed = Tiddler.prototype.changed;
Tiddler.prototype.changed = function()
{
this.disableWikiLinks_changed.apply(this,arguments);
// remove excluded wiki words from links array
var t=store.getTiddlerText(config.options.txtDisableWikiLinksList,"").readBracketedList();
if (t.length) for (var i=0; i<t.length; i++)
if (this.links.contains(t[i]))
this.links.splice(this.links.indexOf(t[i]),1);
};
//}}}
!usage
{{{[img[EU_with_references.png]]}}}
[img[EU_with_references.png]]
!notes
EU flag,
European Union
European regional development fund
Investing in your future
!type
image/png
!file
!url
!data
data:image/png;base64,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
/***
|''Name:''|EbExtrabox.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Extrabox-functionality of TiddlyWiki-ebook|
|''Version:''|1.3|
|''Date:''|May 31, 2012|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131119.1205 ''add'' ''version 1.3''
* "bigbox"-mode elements fullscreen
<<<
<<<
20131010.1437 ''add'' ''version 1.2''
* added extraicon title if it exists
<<<
<<<
20131010.1437 ''fix'' ''version 1.1''
* closing of !bigbox
<<<
<<<
20130930.1451 ''add''
* bigbox: tiddlers tagged with 'modelsolution' are also treated as bigboxes.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* EbExtrabox.js
* Extrabox-functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/************************************************************************
* EbExtrabox -class
************************************************************************/
EbExtrabox = function(boxtype, tiddlerName, place){
if (!boxtype || !tiddlerName || !place){
alert(boxtype +'\n'+ tiddlerName +'\n'+ place +'\n'+ store.tiddlerExists(tiddlerName));
return false;
}
this.place = place;
this.boxtype = boxtype;
this.tiddlerNames = typeof(tiddlerName) == 'string' ? [tiddlerName] : tiddlerName;
this.isopen = false;
this.pagetwoopen = false;
this.pagetwoopen = jQuery('#contentWrapper').attr('pageopen') || false;
}
EbExtrabox.prototype.showIcon = function(){
var extrabox = this;
var extratitle = "";
if(this.tiddlerNames.length === 1){
extratitle = DataTiddler.getData(this.tiddlerNames[0],'extratitle','');
}
this.icon = jQuery('<div'+(extratitle? ' title="'+extratitle.replace(/"/g,"'")+'"' : '' )+' class="extraboxicon extrabox_'+this.boxtype+'"> </div>');
this.icon.click(function(){
if (!extrabox.isopen){
extrabox.open();
}
if (extrabox.boxtype == 'modelsolution' && !extrabox.place.parents('h3').eq(0).hasClass('ui-state-active')){
return true;
} else {
return false;
}
});
jQuery(this.place).append(this.icon);
}
EbExtrabox.prototype.open = function(){
var extrabox = this;
this.extrabox = jQuery('<div class="extraboxwrapper"></div>');
this.extrabox.delegate('.extra_presentationmode_button','click'
,function(event){
jQuery(this).parent().toggleClass('extrabox_fullscreen');
jQuery(this).parent().parent().toggleClass('fullscreenmode');
return false;
});
var tiddlers = [];
var titles = [];
var isbigbox = (this.tiddlerNames.length > 1);
for (var i = 0; i < this.tiddlerNames.length; i++){
this.extrabox.append('<div class="extraboxcontent" tiddler="'+this.tiddlerNames[i]+'"></div>');
tiddlers.push(store.getTiddler(this.tiddlerNames[i]));
titles.push(tiddlers[i] && tiddlers[i].fields && tiddlers[i].fields.ebooktitle);
if (tiddlers[i].isTagged('bigbox') || tiddlers[i].isTagged('modelsolution')){
isbigbox = true;
}
}
if (isbigbox){
this.isbigbox = true;
jQuery('.pageWrapper.hasbigbox .extraboxwrapper.bigbox .extraboxclose').click();
if (this.icon.parents('#pageOneWrapper').length > 0){
var opento = '#pageTwoWrapper';
this.pagetwoopen = jQuery('#contentWrapper').attr('pageopen') || false;
jQuery('#contentWrapper').attr('pageopen', 'bigbox');
} else {
var opento = '#pageOneWrapper';
}
jQuery(opento).addClass('hasbigbox').append(this.extrabox);
} else {
this.icon.append(this.extrabox);
}
var extraclasses = [];
for (var i = 0; i < this.tiddlerNames.length; i++){
var publishbutton = '';
var haspublishbutton = false;
if(tiddlers[i].data() &&tiddlers[i].data().teacherdata && typeof(tiddlers[i].data().teacherdata.published) != "undefined" &&tiddlers[i].data().teacherdata.published == 0 ) {
publishbutton = '<button class="publishbutton" tiddler="'+tiddlers[i].title+'">'+EbookDictionary.localize('publish')+'</button>';
haspublishbutton = true;
}
var wikitext = titles[i] ? '<html><h1 class="extratitle">'+titles[i]+'</h1>'+publishbutton+'</html>\n' : '<html><h1 class="extratitle"> </h1>'+publishbutton+'</html>\n';
wikitext += '{{ebcontent{<<tiddler '+this.tiddlerNames[i]+'>>}}}';
extraclasses.push(tiddlers[i].fields && tiddlers[i].fields.extraclasses);
wikify(wikitext, this.extrabox.find('.extraboxcontent')[i]);
this.extrabox.find('.extraboxcontent').eq(i).append('<div class="extra_presentationmode_button"><ul class="outarrows"><li>↖ ↗</li><li>↙ ↘</li></ul><ul class="inarrows"><li>↘ ↙</li><li>↗ ↖</li></ul></div>');
if(haspublishbutton){
this.extrabox.find('.extraboxcontent[tiddler="'+tiddlers[i].title+'"] button.publishbutton').click(function(){
var t= new Teachertool();
t.publishTiddler = store.getTiddler(jQuery(this).attr('tiddler'));
t.startAuthoring('publish');
//alert("sending..."+jQuery(this).parents('.extraboxcontent').attr('tiddler'));
});
}
}
extraclasses = extraclasses.join(' ');
this.isopen = true;
this.extrabox.append('<div class="extraboxclose">×</div>');
this.icon.parents('.ebookbox').eq(0).attr(this.boxtype+'classes', extraclasses);
if (isbigbox){
this.extrabox.addClass('bigbox');
} else {
this.extrabox.draggable({handler: 'h1.extratitle'});
if (this.extrabox.parents('#pageOne').length > 0 && this.extrabox.parents('[pageopen]').length > 0){
this.extrabox.css('left','50%');
} else {
this.extrabox.css('left','5em');
}
}
this.extrabox.find('.extraboxclose').click(function(){
extrabox.close();
return false;
});
if(typeof(Emathbook.options.user.showstepbystep) !== "undefined" && Emathbook.options.user.showstepbystep){
try{
Emathbook.showStepByStep(jQuery(opento+' div.extraboxwrapper.bigbox'));
} catch (err) {}
}
}
EbExtrabox.prototype.close = function(){
this.icon.parents('.ebookbox').eq(0).attr(this.boxtype+'classes', '');
this.extrabox.remove();
jQuery('.hasbigbox').removeClass('hasbigbox');
this.isopen = false;
if (this.pagetwoopen){
jQuery('#contentWrapper').attr('pageopen', this.pagetwoopen);
} else if (this.isbigbox) {
jQuery('#contentWrapper').removeAttr('pageopen');
}
return false;
}
//}}}
//{{{
/*******************************************************************
* EbHighlight
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/***************************************************
* EbHighlight -class
***************************************************/
EbHighlight = function(){
this.text = '';
this.comments = DataTiddler.getData(Emathbook.config.commenttiddler, 'comments', {});
}
EbHighlight.prototype.showComments = function(){
var tiddlers = jQuery('span[tiddler], div[tiddler]');
for (var i = 0; i<tiddlers.length; i++){
var tiddlerName = tiddlers.eq(i).attr('tiddler');
if (tiddlerName in this.comments){
var tidnode = tiddlers.eq(i);
var tiddly = store.getTiddler(tiddlerName);
var text = tiddly.text;
var rex;
for (var j = 0; j < this.comments[tiddlerName].length; j++){
rex = new RegExp(this.comments[tiddlerName][j].text+'(?!}}})','g');
if (text.match(rex).length > 0){
if (typeof this.comments[tiddlerName][j].comment != 'undefined'){
var ebcomment = '{{ebcomment{'+this.comments[tiddlerName][j].comment+'<html><div title="remove this highlight" id="rmcomm_'+this.comments[tiddlerName][j].commid+'" class="removecomment">×</div><div title="edit this highlight" id="editcomm_'+this.comments[tiddlerName][j].commid+'" class="editcomment">✎</div></html>}}}';
} else {
var ebcomment = '';
var ebcomment = '{{ebcomment{<html><div title="remove this highlight" id="rmcomm_'+this.comments[tiddlerName][j].commid+'" class="removecomment">×</div><div title="edit this highlight" id="editcomm_'+this.comments[tiddlerName][j].commid+'" class="editcomment">✎</div></html>}}}';
}
if (typeof(this.comments[tiddlerName][j].correction) != 'undefined'){
var parts = text.split(rex);
text = parts.slice(0,this.comments[tiddlerName][j].index + 1).join(this.comments[tiddlerName][j].text);
text += '{{highlight{{{ebremoved{'+this.comments[tiddlerName][j].text+'}}}'+this.comments[tiddlerName][j].correction+ebcomment+'}}}';
text += parts.slice(this.comments[tiddlerName][j].index + 1).join(this.comments[tiddlerName][j].text);
// text = text.replace(rex, '{{highlight{{{ebremoved{'+this.comments[tiddlerName][j].text+'}}}'+this.comments[tiddlerName][j].correction+ebcomment+'}}}');
} else {
var parts = text.split(rex);
text = parts.slice(0,this.comments[tiddlerName][j].index + 1).join(this.comments[tiddlerName][j].text);
text += '{{highlight{'+this.comments[tiddlerName][j].text+ebcomment+'}}}';
text += parts.slice(this.comments[tiddlerName][j].index + 1).join(this.comments[tiddlerName][j].text);
// text = text.replace(rex, '{{highlight{'+this.comments[tiddlerName][j].text+ebcomment+'}}}');
}
}
}
tidnode.empty();
wikify(text, tidnode[0], null, tiddly);
tidnode.find('.removecomment').click(function(){
var comments = new EbHighlight();
var tiddlerName = jQuery(this).parents('span[tiddler], div[tiddler]').eq(0).attr('tiddler');
var commid = jQuery(this).attr('id').replace(/^rmcomm_/,'');
comments.tiddler = tiddlerName;
comments.removeComment(commid);
testilogit.commentresprm = comments.submitRemove(commid);
});
tidnode.find('.editcomment').click(function(){
var comments = new EbHighlight();
var tiddlerName = jQuery(this).parents('span[tiddler], div[tiddler]').eq(0).attr('tiddler');
var commid = jQuery(this).attr('id').replace(/^editcomm_/,'');
comments.getComment(tiddlerName, commid);
comments.getNewId();
comments.editComment(commid);
});
}
}
}
EbHighlight.prototype.getSelection = function(){
var selection = window.getSelection();
if ((selection.anchorNode != selection.focusNode) || (jQuery(selection.anchorNode).hasClass('mathquill-rendered-math')) || (jQuery(selection.anchorNode).parents('.mathquill, .mathquill-rendered-math, .sdtable').length > 0)){
alert(EbookDictionary.localize('invalid selection'));
return false;
}
this.text = selection.toString();
if (this.text.length < 1){
alert(EbookDictionary.localize('invalid selection'));
return false;
}
var range = document.createRange();
range.selectNodeContents(jQuery(selection.anchorNode).parents('span[tiddler], div[tiddler]')[0]);
range.setEnd(selection.anchorNode, Math.min(selection.anchorOffset, selection.focusOffset));
var textoffset = range.toString().length;
var textlength = this.text.length;
this.index = 0;
var rex = new RegExp(this.text, 'g');
while (rex.exec(range.toString())){
if (rex.lastIndex - textlength <= textoffset){
this.index++;
} else {
break;
}
}
this.tiddler = jQuery(selection.anchorNode).parents('span[tiddler], div[tiddler]').eq(0).attr('tiddler');
this.getNewId();
this.comment = '';
this.correction = '';
return true;
}
EbHighlight.prototype.getComment = function(tiddlerName, commid){
this.tiddler = tiddlerName;
this.commid = commid;
this.comments = DataTiddler.getData(Emathbook.config.commenttiddler, 'comments', {});
for (var i = 0; i < this.comments[tiddlerName].length; i++){
if (this.comments[tiddlerName][i].commid == commid){
this.text = this.comments[tiddlerName][i].text;
this.index = this.comments[tiddlerName][i].index;
this.comment = this.comments[tiddlerName][i].comment;
this.correction = this.comments[tiddlerName][i].correction;
break;
}
}
}
EbHighlight.prototype.getNewId = function(){
var now = new Date();
this.commid = now.convertToYYYYMMDDHHMMSSMMM() + '_' + config.options.txtUserName;
return this.commid;
}
EbHighlight.prototype.addComment = function(comment, correction){
if (this.tiddler && this.text){
var newComment = {
"commid": this.commid,
"text": this.text,
"index": this.index
};
if (typeof this.comment != 'undefined' && this.comment != ''){
newComment.comment = this.comment;
}
if (typeof this.correction != 'undefined' && this.correction != ''){
newComment.correction = this.correction;
}
this.comments = DataTiddler.getData(Emathbook.config.commenttiddler, 'comments', {});
if (typeof this.comments[this.tiddler] == 'undefined'){
this.comments[this.tiddler] = [];
}
this.comments[this.tiddler].push(newComment);
DataTiddler.setData(Emathbook.config.commenttiddler, 'comments', this.comments);
return true;
} else {
return false;
}
}
EbHighlight.prototype.removeComment = function(commid){
this.comments = DataTiddler.getData(Emathbook.config.commenttiddler, 'comments', {});
for (var i = 0; i < this.comments[this.tiddler].length; i++){
if (this.comments[this.tiddler][i].commid == commid){
this.comments[this.tiddler].splice(i,1);
break;
}
}
this.showComments();
if (this.comments[this.tiddler].length == 0){
delete this.comments[this.tiddler];
}
DataTiddler.setData(Emathbook.config.commenttiddler, 'comments', this.comments);
return true;
}
EbHighlight.prototype.editComment = function(oldcommid){
if (typeof oldcommid == 'undefined'){
oldcommid = '';
}
var commdial = jQuery('<div id="commdial" title="Give your comment">\n<form>\n<fieldset>\n<input hidden="hidden" name="oldcommid" id="oldcommid" value="'+oldcommid+'" /><dl>\n<dt><label>Selected text:</label></dt><dd><span>'+this.text+'</span></dd>\n<dt><label for="correction">Correction</label></dt>\n<dd><input type="text" name="correction" id="correction" class="text ui-widget-content ui-corner-all" value="'+(this.correction||'')+'" /></dd>\n<dt><label for="comment">Your comment</label></dt>\n<dd><textarea name="comment" id="comment" value="" class="text ui-widget-content ui-corner-all">'+(this.comment||'')+'</textarea></dd>\n</dl>\n</fieldset>\n</form></div>');
jQuery('body').append(commdial);
var comment = this;
commdial.dialog({
buttons: {"Ok": function(){
var oldcommid = jQuery('#commdial input#oldcommid').val();
comment.comment = jQuery('#commdial').find('#comment').val();
comment.correction = jQuery('#commdial').find('#correction').val();
comment.addComment(comment.comment,comment.correction);
comment.removeComment(oldcommid);
jQuery( this ).dialog( "close" );
jQuery('#commdial').remove();
testilogit.commentresp = comment.submitComment();
testilogit.commentresprm = comment.submitRemove(oldcommid);
if (Emathbook.config.showcomments){
comment.showComments();
}
}, "Cancel": function(){
jQuery( this ).dialog( "close" );
jQuery('#commdial').remove();
}
}
});
}
EbHighlight.prototype.submitComment = function(){
var response = jQuery.postCORS('http://',
{
"new": "new",
"tiddler": this.tiddler,
"textIndex": this.index,
"commentId": this.commid,
"selText": this.text,
"correction": this.correction,
"comment": this.comment
});
return response;
}
EbHighlight.prototype.submitRemove = function(oldcommid){
var response = jQuery.postCORS('http://',
{
"checkComment": "remove",
"commentId": oldcommid
});
return response;
}
//}}}
<data>{"fracCalc":{"points":700}}</data>
{"name":"chat", "content":"ebookchat", "icon":"chat.png","openpage":true},{"name":"comments", "content":"ebookcomments","icon":"icon-comment.png","refresh":true,"openpage":true}
<data>{"ebookapps":[{"name":"calculator", "content":"ebookcalculator","icon":"calculator.png","openpage":true},{"name":"nextpage", "content":"ebookopening","icon":"Book_two_pages.png","refresh":true,"openpage":true},{"name":"onepage", "content":"ebookclosepagetwo","icon":"Book_one_page.png","refresh":false,"openpage":false}]}</data>
<data>{"ebookapps":[{"name":"comments", "content":"ebookcomments","icon":"icon-comment.png","refresh":true,"openpage":true}]}</data>
<<showData>>
<data>{"comments":{"textelement_4_data":[{"commid":"20111205.0812172110_pesasa","text":"Ne","index":1,"comment":"joo","correction":"joo"}]}}</data>
<data>{"ebookapps":[{"name":"coursecomments", "content":"ebookcoursecomments","icon":"icon-comment-course.png","refresh":true,"openpage":"coursecomment"}]}</data>
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<div class='ebooktitle'>Ebook title:<span macro='edit ebooktitle'></span></div>
<div class='ebookcontainer'>Container:<span macro='edit container'></span></div>
<!--<div class='editupPage'>Up page:<br /><span macro='edit uppage'></span></div>-->
<!--}}}-->
//{{{
var elementFunctions={};
/***********************************************
* EbElement -class
* One solution element (text, structured derivation,...)
***********************************************/
EbElement = function(options, editable){
options = options || {};
this.type = options.type || 'text';
this.data = options.data || '';
this.editable = editable;
}
EbElement.prototype.getWiki = function(iseditable){
var wikitext = '{{ebelement{\n';
if (this.editable && typeof(iseditable) === 'undefined'){
iseditable = 'edit';
}
iseditable = (iseditable ? ' ' + iseditable : '');
try{
wikitext += elementFunctions['getWiki'+this.type](this.data,iseditable );
}catch(e){
wikitext += 'error '+e;
}
wikitext += '}}}';
return wikitext;
}
EbElement.prototype.getData = function(){
return {"type": this.type, "data": this.data};
}
//}}}
testilogit={};var _;function QedEditor(d,c,b,a){this.extraparams={};if(typeof(a)!="undefined"){this.extraparams=a}this.name=d;this.context=b;this.element=jQuery('<div class="qededitor qedcontext'+this.context+'"></div>');jQuery(c).append(this.element);this.element[0].editor=this;this.plugins=[];this.derivation=new SdDerivation(this.context,this);this.open(this.name);this.undoStack=new Eventstack(0);this.redoStack=new Eventstack(0);this.nextFocus="";this.installPlugins();this.init()}QedEditor.inited=false;QedEditor.options={lang:"en"};QedEditor.locales={task:{en:"task",fi:"tehtävä",sv:"uppgift",et:"ülesanne"},taskass:{en:"assumption",fi:"oletus",sv:"antagande",et:"eeldus"},assumption:{en:"assumption",fi:"oletus",sv:"antagande",et:"eeldus"},taskobs:{en:"observation",fi:"havainto",sv:"observation",et:"tähelepanek"},observation:{en:"observation",fi:"havainto",sv:"observation",et:"tähelepanek"},term:{en:"term",fi:"termi",sv:"term",et:"avaldis"},relation:{en:"relation",fi:"relaatio",sv:"relation",et:"seos"},motivation:{en:"motivation",fi:"perustelu",sv:"motivering",et:"selgitus"},step:{en:"step",fi:"askel",sv:"steg",et:"samm"},subderivation:{en:"subderivation",fi:"alipäättely",sv:"delhärledning",et:"alalahendus"},derivation:{en:"derivation",fi:"päättelyketju",sv:"härledning",et:"lahendus"},derivationmotivation:{en:"derivationmotivation",fi:"päättelyketjun perustelu",sv:"motivering av härledningen",et:"lahenduse selgitus"},Undo:{en:"undo",fi:"kumoa",sv:"Ã¥ngra",et:"tühista käsk"},Redo:{en:"redo",fi:"tee uudelleen",sv:"Ã¥terställ",et:"taasta käsk"},relations:{en:"relations",fi:"relaatiot",sv:"relationer",et:"seosed"},misc:{en:"misc",fi:"sekalaista",sv:"övrigt",et:"mitmesugust"},greeks:{en:"greeks",fi:"kreikkalaiset",sv:"grekiska",et:"kreeka"}};QedEditor.options.TiddlyWiki={saveTiddler:"QedDerivationsData",recycleTiddler:"QedDerivationsRecycleBin"};_=QedEditor.prototype;_.init=function(){if(typeof(QedEditor.inited)=="undefined"||!QedEditor.inited){jQuery(document).keyup(function(f){if(f.keyCode=="13"&&(f.ctrlKey||f.altKey)){if(f.shiftKey){var d=jQuery(".qededitor.qedediting");if(typeof(QedEditor.buttonpanel.lastfocus)!="undefined"){var c=(QedEditor.buttonpanel.lastfocus).parents(".qededitor");var b=d.index(c);var a=d.eq((b+1)%d.length).find(".mathquill-editable").last();a.focus()}else{var a=jQuery(".qededitor .mathquill-editable").eq(0);a.focus()}}else{if(typeof(QedEditor.buttonpanel.lastfocus)!="undefined"){var a=jQuery(QedEditor.buttonpanel.lastfocus);a.focus()}else{var a=jQuery(".qededitor .mathquill-editable");a.focus()}}testilogit.focuselem=a;a.parents(".qededitor")[0].editor.scrollInView(a)}});QedEditor.inited=true}if(this.context=="moodlesa"&&(jQuery(this.element).parent().hasClass("qedsaveajax")||jQuery(this.element).parent().hasClass("qedajaxsave"))){this.derivation.saveajax=true}else{this.derivation.saveajax=false}};_.show=function(){var a=this.derivation.html("show");jQuery(this.element).empty().append(a);this.element.find(".mathquill-editable").mathquill("editable");this.element.find(".mathquill-textbox").mathquill("textbox");this.element.find(".mathquill-embedded-latex").mathquill();this.element.find("a.command_qededit").click(function(){jQuery(this).parents(".qededitor")[0].editor.edit();return false});this.element.find("td.ldots").click(function(){var d=jQuery(this).next().attr("loc");var h=d.split("_");var j=h[h.length-2];if(j=="observation"){h.push("motivation")}else{if(j=="term"){h[h.length-2]="motivation";h[h.length-1]=parseInt(h[h.length-1])-1}}var k=h.join("_");var l=jQuery(this).parents(".qededitor")[0].editor;var e=l.derivation;var b=e.findLocation(k);b.switchHideSubders();l.save();var c=k+"_subderivation_";var g=jQuery(this).parent().siblings().children('td[loc*="'+c+'"]');var m=g.parent();for(var f=0;f<m.length;f++){if(m.eq(f).hasClass("sdhidden")){g.eq(f).children("div.sdsubderivation").hide();m.eq(f).removeClass("sdhidden");g.eq(f).children("div.sdsubderivation").slideDown("slow");g.eq(f).find(".mathquill-rendered-math").mathquill("redraw")}else{g.eq(f).children("div.sdsubderivation").slideUp("slow",function(){jQuery(this).parents("tr").eq(0).addClass("sdhidden");jQuery(this).children("div.subderivation").show()})}}})};_.edit=function(){if(jQuery("#mathbuttonpanel").length==0){jQuery("#mathbuttonwrapper").append(QedEditor.buttonpanel.html(""));QedEditor.buttonpanel.initClicks()}var b="";var c='<div class="structuredderivation" sdname="'+this.name+'">\n';c+='<div class="qededitorbuttons">\n';c+='<a href="javascript:;" class="button command_qedclose command_editorclose" title="Close"></a>\n';b=this.undoStack.isempty()?"":" active";c+='<a href="javascript:;" class="button command_qedundo command_editorundo'+b+'" title="Undo"><span>↶</span></a>\n';b=this.redoStack.isempty()?"":" active";c+='<a href="javascript:;" class="button command_qedredo command_editorredo'+b+'" title="Redo"><span>↷</span></a>\n';c+=this.pluginButtons();c+="</div>\n";c+=this.derivation.html("edit",this.name);c+="\n</div>";var a=jQuery(this.element);a.empty().append(c);a.find("div.structuredderivation").addClass("sdediting");a.addClass("qedediting");this.element.find(".mathquill-editable").mathquill("editable");this.element.find(".mathquill-textbox").mathquill("textbox");this.element.find(".mathquill-embedded-latex").mathquill();this.element.find("td.ldots").click(function(){var f=jQuery(this).next().attr("loc");var k=f.split("_");var l=k[k.length-2];if(l=="observation"){k.push("motivation")}else{if(l=="term"){k[k.length-2]="motivation";k[k.length-1]=parseInt(k[k.length-1])-1}}var m=k.join("_");var n=jQuery(this).parents(".qededitor")[0].editor;var g=n.derivation;var d=g.findLocation(m);d.switchHideSubders();n.save();var e=m+"_subderivation_";var j=jQuery(this).parent().siblings().children('td[loc*="'+e+'"]');var o=j.parent();for(var h=0;h<o.length;h++){if(o.eq(h).hasClass("sdhidden")){j.eq(h).children("div.sdsubderivation").hide();o.eq(h).removeClass("sdhidden");j.eq(h).children("div.sdsubderivation").slideDown("slow");j.eq(h).find(".mathquill-rendered-math").mathquill("redraw")}else{j.eq(h).children("div.sdsubderivation").slideUp("slow",function(){jQuery(this).parents("tr").eq(0).addClass("sdhidden");jQuery(this).children("div.subderivation").show()})}}});a.find("a.command_qedclose").click(function(){var d=jQuery(this).parents("div.structuredderivation");d.removeClass("sdediting");d.parents(".qededitor").eq(0).removeClass("qedediting");$editor=d.parents("div.qededitor");$editor[0].editor.save();$editor[0].editor.show();if(jQuery(".sdediting").length==0){jQuery("#mathbuttonpanel").remove()}return false});a.find("a.command_qedundo").click(function(){jQuery(this).parents("div.qededitor")[0].editor.undo();return false});a.find("a.command_qedredo.active").click(function(){jQuery(this).parents("div.qededitor")[0].editor.redo();return false});a.find("a.command_qedredo").not(".active").click(function(){return false});a.find(".mathquill-editable").focusout(function(k){$mqbox=jQuery(this);var f=$mqbox.parents("div.qededitor");var m=$mqbox.parents("td").attr("loc");var n=$mqbox.parents("td").attr("class");var g=f[0].editor.derivation;var j=g.findLocation(m);QedEditor.buttonpanel.lastfocus=$mqbox;$mqbox.parents("tr:eq(0)").removeClass("sdeditfocuson");var d=$mqbox.mathquill("latex").replace(/</g,"\\lt ").replace(/>/g,"\\gt ");var l=g.findLocation(m).text;if(l!=d){if(typeof(j.virgin)!="undefined"&&j.virgin){$mqbox.parents("td.virgin").removeClass("virgin")}$mqbox.parents(".qededitor").eq(0).find("a.command_qedundo").addClass("active");$mqbox.parents(".qededitor").eq(0).find("a.command_qedredo").removeClass("active");var h=[d,l];var i=new EditorEvent("edit",n,m,"",h);f[0].editor.doEvent(i)}}).click(function(){jQuery(this).parents("tr:eq(0)").addClass("sdeditfocuson")}).focus(function(){jQuery(this).parents("tr:eq(0)").addClass("sdeditfocuson")});a.find(".mathquill-editable").keyup(function(n){var m=jQuery(this).parents(".qededitor")[0].editor;if(n.keyCode=="13"&&!(n.ctrlKey||n.altKey)){jQuery(n.currentTarget).focusout().blur()}else{if(n.keyCode=="38"&&(n.ctrlKey||n.altKey)){var g=jQuery(n.currentTarget).parents(".qededitor").eq(0).find(".mathquill-editable:visible");var k=g.index(jQuery(n.currentTarget));if(k>0){jQuery(n.currentTarget).focusout().blur();g.eq(k-1).focus();m.scrollInView(g.eq(k-1))}}else{if(n.keyCode=="40"&&(n.ctrlKey||n.altKey)){var g=jQuery(n.currentTarget).parents(".qededitor").eq(0).find(".mathquill-editable:visible");var k=g.index(jQuery(n.currentTarget));if(k<g.length-1){jQuery(n.currentTarget).focusout().blur();g.eq(k+1).focus();m.scrollInView(g.eq(k+1))}}else{if(n.keyCode=="13"&&(n.ctrlKey||n.altKey)){var j=jQuery(this).parents("td").eq(0);var o=j.parents("tr").eq(0);jQuery("#qededitormenuwrapper").remove();o.find("td").eq(1).append('<div id="qededitormenuwrapper"></div>');var l=o.find("#qededitormenuwrapper");var f={minus:[],plus:[],undo:!m.undoStack.isempty(),redo:!m.redoStack.isempty()};var i=o.find(".sdbeforebuttons .minusbuttons");if(i.attr("menuitems")){f.minus=i.attr("menuitems").split(" ")}var h=o.find(".sdafterbuttons .plusbuttons");if(h.attr("menuitems")){f.plus=h.attr("menuitems").split(" ")}var d=new QedEditorMenu(f);l.append(d.html());d.menuInit();n.stopPropagation();n.preventDefault()}else{}}}}});a.find(".sdbeforebuttons").click(function(j){var g=jQuery(this).parents(".qededitor")[0].editor;var f=jQuery(this).parents("td").eq(0);jQuery("#qededitormenuwrapper").remove();jQuery(this).append('<div id="qededitormenuwrapper" class="minus"></div>');var d=f.find("#qededitormenuwrapper");var k={minus:[],plus:[],undo:false,redo:false};var i=f.find(".minusbuttons");if(i.attr("menuitems")){k.minus=i.attr("menuitems").split(" ")}var h=new QedEditorMenu(k);d.append(h.html());h.menuInit()});a.find(".sdafterbuttons").click(function(j){var h=jQuery(this).parents(".qededitor")[0].editor;var g=jQuery(this).parents("td").eq(0);jQuery("#qededitormenuwrapper").remove();jQuery(this).append('<div id="qededitormenuwrapper" class="plus"></div>');var d=g.find("#qededitormenuwrapper");var k={minus:[],plus:[],undo:false,redo:false};var f=g.find(".plusbuttons");if(f.attr("menuitems")){k.plus=f.attr("menuitems").split(" ")}var i=new QedEditorMenu(k);d.append(i.html());i.menuInit()});this.initPlugins();this.setFocus()};_.doEvent=function(c){if(c.event!="undo"&&c.event!="redo"){var a=this.derivation.eventDo(c);if(c.event=="remove"&&c.item=="subderivation"){for(var b=0;b<a.length;b++){this.deleteDeriv(a[b],true)}}this.redoStack.clear();this.undoStack.push(c.invert())}else{if(c.event=="undo"){this.undo()}else{if(c.event=="redo"){this.redo()}}}this.save();if(c.event!="edit"&&c.event!="undo"&&c.event!="redo"){this.edit()}};_.undo=function(){var f=this.undoStack.pop();if(typeof(f)!="undefined"){if(f.event=="add"&&f.item=="subderivation"){var e=this.getDerNames(f.newData());for(var b=0;b<e.length;b++){this.recycleCancel(e[b])}var d=this.getDerivs(this.derivation.name);var a=new SdSubDeriv(f.newData(),this.context,this.editor,d);var c=new EditorEvent(f.event,f.item,f.location,f.position,[a,""]);this.derivation.eventDo(c)}else{this.derivation.eventDo(f)}this.redoStack.push(f.invert());this.save();this.edit()}};_.redo=function(){var a=this.redoStack.pop();if(typeof(a)!="undefined"){this.derivation.eventDo(a);this.undoStack.push(a.invert());this.save();this.edit()}};_.setFocus=function(a){if(typeof(a)=="undefined"){a=this.nextFocus}if(a==""){a=jQuery(this.element).find(".mathquill-editable").eq(0).parents("td").attr("loc")}var b=jQuery(this.element).find("td:[loc="+a+"] .mathquill-editable");if(b.length>0){b.focus()}else{var c=jQuery(this.element).find("td.term");a=c.eq(c.length-1).attr("loc");this.setFocus(a)}};_.scrollInView=function(d){switch(this.context){case"moodlesa":var c=jQuery(window);var b=jQuery("html");var e=0;var a=b.scrollTop();break;case"tiddlywiki":var c=jQuery("#displayArea");var b=c;var e=b.scrollTop()-b.offset().top;var a=b.offset().top;break;default:var c=jQuery(window);var b=jQuery("html")}if(jQuery(d).offset().top-a>c.height()-120){b.stop();b.animate({scrollTop:jQuery(d).offset().top+e+150-c.height()},300)}if(jQuery(d).offset().top-a<120){b.stop();b.animate({scrollTop:jQuery(d).offset().top+e-150},300)}};_.derivationExists=function(c){if(typeof(g)=="undefined"){var g={}}switch(this.context){case"tiddlywiki":var i;var e=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){e=this.extraparams.tiddler}i=(typeof(DataTiddler.getData(e,"derivations",{})[c])!="undefined");return i;break;case"moodlesa":var b=this.name;var a=jQuery("#"+b+' .ablock input[type="text"]');var d=a.val();var h="{}";try{h=JSON.parse(d)}catch(f){h={derivations:{},recycled:{}}}if(typeof(h.derivations)=="undefined"){h.derivations={}}return(typeof(h.derivations[c])!="undefined");break;case"moodledesc":var b=this.name;var a=jQuery("#"+b+" .qtext .data");var d=a.html();var h="{}";try{h=JSON.parse(d)}catch(f){h={derivations:{},recycled:{}}}if(typeof(h.derivations)=="undefined"){h.derivations={}}return(typeof(h.derivations[c])!="undefined");default:return false}};_.getDerivsWithPrefix=function(g){if(typeof(h)=="undefined"){var h={}}switch(this.context){case"tiddlywiki":var k=[];var e=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){e=this.extraparams.tiddler}var c=g.length;var j=DataTiddler.getData(e,"derivations",{});for(name in j){if(name.substr(0,c)==g){k.push(name)}}return k;break;case"moodlesa":var b=this.name;var a=jQuery("#"+b+' .ablock input[type="text"]');var d=a.val();var i="{}";try{i=JSON.parse(d)}catch(f){i={derivations:{},recycled:{}}}if(typeof(i.derivations)=="undefined"){i.derivations={}}k=[];var c=g.length;var j=i.derivations;for(name in j){if(name.substr(0,c)==g){k.push(name)}}return k;break;case"moodledesc":var b=this.name;var a=jQuery("#"+b+" .qtext .data");var d=a.html();var i="{}";try{i=JSON.parse(d)}catch(f){i={derivations:{},recycled:{}}}if(typeof(i.derivations)=="undefined"){i.derivations={}}k=[];var c=g.length;var j=i.derivations;for(name in j){if(name.substr(0,c)==g){k.push(name)}}return k;default:return false}};_.open=function(b){var a=this.getDerivs(b);this.derivation.init(b,a)};_.getDerivs=function(f,c,b){if(typeof(c)=="undefined"){c=this.context}if(typeof(b)=="undefined"){b=this.extraparams.tiddler}var e={};switch(c){case"tiddlywiki":var d=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(b)!="undefined"){d=b}e[f]=this.getTiddlyDeriv(f,d);var g=this.getDerivsWithPrefix(f+"sub");for(var a=0;a<g.length;++a){e[g[a]]=this.getTiddlyDeriv(g[a],d)}break;case"moodlesa":e[f]=this.getMoodleSADeriv(f);var g=this.getDerivsWithPrefix(f+"sub");for(var a=0;a<g.length;++a){e[g[a]]=this.getMoodleSADeriv(g[a],d)}break;case"moodledesc":e[f]=this.getMoodleDescDeriv(f);var g=this.getDerivsWithPrefix(f+"sub");for(var a=0;a<g.length;++a){e[g[a]]=this.getMoodleDescDeriv(g[a],d)}break;default:e[f]={}}return e};_.getTiddlyDeriv=function(d,c){var e;var a={};a[d]={task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};var b=DataTiddler.getData(c,"derivations",a);if(typeof(b[d])=="undefined"){e=a[d]}else{e=b[d]}return e};_.getMoodleSADeriv=function(e){var a=this.name;var f=jQuery("#"+a+' .ablock input[type="text"]');var d=f.val();var b="{}";try{b=JSON.parse(d)}catch(c){b={derivations:{},recycled:{}}}if(typeof(b.derivations)=="undefined"){b.derivations={}}var g=(typeof(b.derivations[e])!="undefined")?b.derivations[e]:{task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};return g};_.getMoodleDescDeriv=function(e){var a=this.name;var f=jQuery("#"+a+" .qtext .data");var d=f.html();var b="{}";try{b=JSON.parse(d)}catch(c){b={derivations:{},recycled:{}}}if(typeof(b.derivations)=="undefined"){b.derivations={}}var g=(typeof(b.derivations[e])!="undefined")?b.derivations[e]:{task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};return g};_.getDerNames=function(e,c,b){if(typeof(c)=="undefined"){c=this.context}if(typeof(b)=="undefined"){b=this.extraparams.tiddler}var a=[];switch(c){case"tiddlywiki":var d=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(b)!="undefined"){d=b}a=this.getTiddlyDerNames(e,d);break;case"moodlesa":a=this.getMoodleSADerNames(e);break;case"moodledesc":a=this.getMoodleDescDerNames(e);break;default:break}return a};_.getTiddlyDerNames=function(g,f){var a=[g];var h;var d={};d[g]={task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};var e=DataTiddler.getData(f,"derivations",d);if(typeof(e[g])=="undefined"){h=d[g]}else{h=e[g]}for(var c=0;c<h.observation.length;c++){for(var b=0;b<h.observation[c].motivation.subderiv.length;b++){a=a.concat(this.getTiddlyDerNames(h.observation[c].motivation.subderiv[b],f))}}for(var c=0;c<h.motivation.length;c++){for(var b=0;b<h.motivation[c].subderiv.length;b++){a=a.concat(this.getTiddlyDerNames(h.motivation[c].subderiv[b],f))}}return a};_.getMoodleSADerNames=function(g){var b=this.name;var a=jQuery("#"+b+' .ablock input[type="text"]');var d=a.val();var l="{}";var k=[g];try{l=JSON.parse(d)}catch(e){l={derivations:{},recycled:{}}}if(typeof(l.derivations)=="undefined"){l.derivations={}}var c=(typeof(l.derivations[g])!="undefined")?l.derivations[g]:{task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};for(var h=0;h<c.observation.length;h++){for(var f=0;f<c.observation[h].motivation.subderiv.length;f++){k=k.concat(this.getTiddlyDernames(c.observation[h].motivation.subderiv[f]))}}for(var h=0;h<c.motivation.length;h++){for(var f=0;f<c.motivation[h].subderiv.length;f++){k=k.concat(this.getTiddlyDernames(c.motivation[h].subderiv[f]))}}return k};_.getMoodleDescDerNames=function(g){var b=this.name;var a=jQuery("#"+b+" .qtext .data");var d=a.html();var l="{}";var k=[g];try{l=JSON.parse(d)}catch(e){l={derivations:{},recycled:{}}}if(typeof(l.derivations)=="undefined"){l.derivations={}}var c=(typeof(l.derivations[g])!="undefined")?l.derivations[g]:{task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};for(var h=0;h<c.observation.length;h++){for(var f=0;f<c.observation[h].motivation.subderiv.length;f++){k=k.concat(this.getTiddlyDernames(c.observation[h].motivation.subderiv[f]))}}for(var h=0;h<c.motivation.length;h++){for(var f=0;f<c.motivation[h].subderiv.length;f++){k=k.concat(this.getTiddlyDernames(c.motivation[h].subderiv[f]))}}return k};_.save=function(b){if(typeof(b)=="undefined"){b=this.derivation.name}switch(this.context){case"tiddlywiki":var a=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){a=this.extraparams.tiddler}this.saveTiddly(a,b);break;case"moodlesa":this.saveMoodleSA(b);break;case"moodledesc":break;default:return"Invalid context!"}};_.saveTiddly=function(c,d){var b=this.derivation.getSaveData();var f=DataTiddler.getData(c,"derivations",{});for(var a=0;a<b.length;a++){f[b[a].name]=b[a].data;if(typeof(f[b[a].name].plugindata)!="undefined"){b[a].data.plugindata=f[b[a].name].plugindata}}var e=config.options.chkAutoSave;config.options.chkAutoSave=false;DataTiddler.setData(c,"derivations",f);config.options.chkAutoSave=e};_.saveMoodleSA=function(f){if(typeof(f)=="undefined"){f=this.name}var b=f.replace(/sub[0-9]+$/,"");var a=jQuery("#"+b+' .ablock input[type="text"]');var d=a.val();var l="{}";try{l=JSON.parse(d)}catch(e){l={derivations:{},recycled:{}}}if(typeof(l.derivations)=="undefined"){l.derivations={}}var k=this.derivation.getSaveData();for(var g=0;g<k.length;g++){if(typeof(l.derivations[k[g].name])!="undefined"&&typeof(l.derivations[k[g].name].plugindata)!="undefined"){k[g].data.plugindata=l.derivations[k[g].name].plugindata}l.derivations[k[g].name]=k[g].data}d=JSON.stringify(l);a.val(d);if(this.saveajax){var c=$("form#responseform").attr("action")+"#"+b;var j=jQuery('<div class="ajaxanswer"></div>');var h={};h["resp"+b.slice(1)+"_"]=d;h["resp"+b.slice(1)+"_submit"]="Submit";h.timeup=0;h.questionids=b.slice(1);testilogit.ajaxresponse=jQuery.post(c,h)}};_.deleteDeriv=function(c,b){switch(this.context){case"tiddlywiki":if(!b){var a=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){a=this.extraparams.tiddler}this.deleteTiddly(a,c)}else{var a=QedEditor.options.TiddlyWiki.recycleTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){a=this.extraparams.tiddler}this.recycleTiddly(a,c)}break;case"moodlesa":if(!b){this.deleteMoodleSA(c)}else{this.recycleMoodleSA(c)}break;case"moodledesc":break;default:return"Invalid context!"}};_.deleteTiddly=function(a,b){var c=DataTiddler.getData(a,"derivations",{});delete c[b];DataTiddler.setData(a,"derivations",c)};_.deleteMoodleSA=function(e){var a=this.name;var f=jQuery("#"+a+' .ablock input[type="text"]');var d=f.val();var b="{}";try{b=JSON.parse(d)}catch(c){b={derivations:{},recycled:{}}}delete b.derivations[this.name];d=JSON.stringify(b);f.val(d)};_.recycleTiddly=function(a,c){var d=DataTiddler.getData(a,"recycled",{});var b=d[this.derivation.name];if(typeof(b)=="undefined"){b=[]}if(b.indexOf(c)==-1){b.push(c)}d[this.derivation.name]=b;DataTiddler.setData(a,"recycled",d)};_.recycleMoodleSA=function(f){var a=this.name;var g=jQuery("#"+a+' .ablock input[type="text"]');var e=g.val();var b="{}";try{b=JSON.parse(e)}catch(c){b={derivations:{},recycled:{}}}if(typeof(b.recycled)=="undefined"){b.recycled={}}var d=b.recycled[this.derivation.name];if(typeof(d)=="undefined"){d=[]}if(d.indexOf(f)==-1){d.push(f)}b.recycled[this.derivation.name]=d;e=JSON.stringify(b);g.val(e)};_.recycleCancel=function(b){switch(this.context){case"tiddlywiki":var a=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){a=this.extraparams.tiddler}this.recycleCancelTiddly(a,b);break;case"moodlesa":this.recycleCancelMoodleSA(b);break;default:return"Invalid context!"}};_.recycleCancelTiddly=function(a,c){var e=DataTiddler.getData(a,"recycled",{});var b=(typeof(e[this.derivation.name])!="undefined")?e[this.derivation.name]:[];var d=b.indexOf(c);if(d!=-1){b.splice(d,1)}if(b.length==0){delete e[this.derivation.name]}DataTiddler.setData(a,"recycled",e)};_.recycleCancelMoodleSA=function(f){var a=this.name;var h=jQuery("#"+a+' .ablock input[type="text"]');var e=h.val();var b="{}";try{b=JSON.parse(e)}catch(c){b={derivations:{},recycled:{}}}if(typeof(b.recycled)=="undefined"){b.recycled={}}var d=b.recycled[this.derivation.name];if(typeof(d)=="undefined"){d=[]}var g=d.indexOf(f);if(g!=-1){d.splice(g,1)}if(d.length==0){delete b.recycled[this.derivation.name]}else{b.recycled[this.derivation.name]=d}e=JSON.stringify(b);h.val(e)};_.cleanRecycleBin=function(){switch(this.context){case"tiddlywiki":var a=QedEditor.options.TiddlyWiki.recycleTiddler;if(typeof(this.extraparams.tiddler)!="undefined"){a=this.extraparams.tiddler}this.cleanRecycleBinTiddly(a);break;default:break}};_.cleanRecycleBinTiddly=function(c){var a=DataTiddler.getData(c,"recycled",{});var d=a[this.derivation.name];for(var b=0;b<d.length;b++){this.deleteDeriv(d[b])}delete a[this.derivation.name];DataTiddler.setData(c,"recycled",a)};QedEditor.oprHandler=function(o){var a=jQuery(this).parents("div.qededitor");var d=o.data.loc.replace(/_motivation$/,"").split("_"+o.data.splitelem+"_");var h=parseInt(d.pop());var p=d.join("_"+o.data.splitelem+"_");testilogit.data=o.data;var c=a[0].editor.derivation.findLocation(p);var g=["",""];switch(o.data.oper){case"add":switch(o.data.elem){case"task":var n=c.term[0].text.replace(/\\text{([^{}]*)}/g,"$$$1$$");n=("$"+n+"$").replace(/\$\$/g,"");g=[n,""];h=0;a[0].editor.nextFocus=p+"_task_0";break;case"taskass":var n=c.term[0].text.replace(/\\text{([^{}]*)}/g,"$$$1$$");n=("$"+n+"$").replace(/\$\$/g,"");g=[n,c.term[0].text];h=0;a[0].editor.nextFocus=p+"_assumption_0";break;case"taskobs":var n=c.term[0].text.replace(/\\text{([^{}]*)}/g,"$$$1$$");n=("$"+n+"$").replace(/\$\$/g,"");g=[n,c.term[0].text];h=0;a[0].editor.nextFocus=p+"_observation_0_motivation";break;case"assumption":if(o.data.splitelem=="task"){h=0}else{h=h+1}a[0].editor.nextFocus=p+"_assumption_"+h;break;case"observation":if(o.data.splitelem=="task"||o.data.splitelem=="assumption"){h=0}else{h=h+1}a[0].editor.nextFocus=p+"_observation_"+h+"_motivation";break;case"step":var q="";if(h<1){q=(typeof(c.relation[0])!="undefined")?c.relation[0].text:""}else{if(h>c.relation.length-1){q=c.relation[c.relation.length-1].text}else{q=c.relation[h-1].text}}var r={text:"",subders:[]};var k=c.term[h].text;g=[{relation:q,motivation:r,term:k},""];if(q==""){a[0].editor.nextFocus=p+"_relation_"+h}else{a[0].editor.nextFocus=p+"_motivation_"+h}break;case"subderivation":if(o.data.splitelem=="motivation"||o.data.splitelem=="observation"){p=o.data.loc;h=0}else{if(o.data.splitelem=="term"){d=p.split("_subderivation_");h=parseInt(d.pop())+1;p=d.join("_subderivation_")}else{p=o.data.loc.replace(/_subderivation_[0-9]+$/,"");h=parseInt(d[d.length-1])+1}}a[0].editor.nextFocus=p+"_subderivation_"+h+"_term_0";break;case"derivationmotivation":a[0].editor.nextFocus=p+"_derivmotivation_0";break;default:alert(o.data.oper+"\n"+o.data.elem);break}break;case"remove":switch(o.data.elem){case"task":g=["",c.task[0].text];h=0;a[0].editor.nextFocus=p+"_term_0";break;case"taskass":g=["",c.task[0].text];h=0;a[0].editor.nextFocus=p+"_term_0";break;case"taskobs":g=["",c.task[0].text];h=0;a[0].editor.nextFocus=p+"_term_0";break;case"assumption":g=["",c.assumption[h].text];if(c.assumption.length==1){a[0].editor.nextFocus=p+"_task_0"}else{if(c.assumption.length>h+1){a[0].editor.nextFocus=p+"_assumption_"+h}else{a[0].editor.nextFocus=p+"_assumption_"+(h-1)}}break;case"observation":g=["",c.observation[h]];if(c.observation.length==1){if(c.assumption.length>0){a[0].editor.nextFocus=p+"_assumption_"+(c.assumption.length-1)}else{a[0].editor.nextFocus=p+"_task_0"}}else{if(c.observation.length>h+1){a[0].editor.nextFocus=p+"_observation_"+h}else{a[0].editor.nextFocus=p+"_observation_"+(h-1)}}break;case"step":var j=c.relation[h].text;var m={text:c.motivation[h].text,subders:[]};for(var f=0;f<c.motivation[h].subderivation.length;f++){m.subders.push(c.motivation[h].subderivation[f].name)}var s=c.term[h+1].text;g=["",{relation:j,motivation:m,term:s}];a[0].editor.nextFocus=p+"_term_"+h;break;case"derivationmotivation":g=["",c.derivmotivation[0].text];a[0].editor.nextFocus=p+"_term_0";break;case"subderivation":d=p.split("_subderivation_");h=parseInt(d.pop());p=d.join("_subderivation_");var b=a[0].editor.derivation.findLocation(p).subderivation[h].name;g=["",b];a[0].editor.nextFocus=p;break;default:alert(o.data.oper+"\n"+o.data.elem);break}break;case"undo":case"redo":p="";h="";g=["",""];break;default:break}var l=new EditorEvent(o.data.oper,o.data.elem,p,h,g);a[0].editor.doEvent(l);jQuery("#qededitormenuwrapper").remove();return false};_.installPlugins=function(){for(var a=0;a<QedEditor.plugins.length;a++){if(typeof(QedEditor.plugins[a])!="undefined"){this.plugins.push(QedEditor.plugins[a].use(this))}}};_.pluginButtons=function(){var b="";for(var a=0;a<this.plugins.length;a++){b+=this.plugins[a].html()}return b};_.initPlugins=function(){var b=jQuery(this.element).find(".qededitorbuttons .pluginbuttons");for(var c=0;c<this.plugins.length;c++){try{this.plugins[c].init()}catch(f){}var d=b.eq(c).find("li.pluginitem a.pluginbutton");for(var a=0;a<this.plugins[c].buttons.length;a++){var g={editor:this,plugin:this.plugins[c]};d.eq(a).click(function(){jQuery(this).parents("ul").eq(0).hide();setTimeout("jQuery('.pluginbuttons ul').attr('style','')",500);return false});d.eq(a).click(g,this.plugins[c].buttons[a].action)}}};function QedEditorMenu(a){this.menuitems=[];var c;for(var b=0;b<a.plus.length;b++){c=new QedEditorMenuItem("plus",a.plus[b]);this.menuitems.push(c)}for(var b=0;b<a.minus.length;b++){c=new QedEditorMenuItem("minus",a.minus[b]);this.menuitems.push(c)}if(a.undo){c=new QedEditorMenuItem("undo","Undo");this.menuitems.push(c)}if(a.redo){c=new QedEditorMenuItem("redo","Redo");this.menuitems.push(c)}}_=QedEditorMenu.prototype;_.html=function(){var a="";for(var b=0;b<this.menuitems.length;b++){a+=this.menuitems[b].html()}a='<ul id="qededitormenu">\n'+a+"</ul>\n";return a};_.menuInit=function(){jQuery("#qededitormenu").parents("td").eq(0).find(".mathquill-editable").blur().focusout();jQuery("#qededitormenu a").eq(0).focus();jQuery("#qededitormenu li").eq(0).addClass("selected");jQuery("#qededitormenu li").each(function(){var a=jQuery(this).parents("tr").eq(0).find("td").eq(1);if(a.attr("class").match(/relation/gi)=="relation"){var c="relation";var b=a.attr("loc")}else{var c=a.attr("class").match(/(task|term|relation|motivation|assumption|observation|obsmotivation|derivmotivation|subderivation)/gi)[0].replace("obsmotivation","observation");var b=a.attr("loc")}var f={"+":"add","–":"remove","\u21b6":"undo","\u21b7":"redo"};var g=f[jQuery(this).find(".menuoperation").html()];var d=jQuery(this).find(".menuname").html();var e={oper:g,elem:d,loc:b,splitelem:c};jQuery(this).click(e,QedEditor.oprHandler);jQuery(this).mouseenter(function(){jQuery(this).addClass("selected")});jQuery(this).mouseleave(function(){jQuery(this).removeClass("selected")});jQuery(this).keydown(function(h){if(h.keyCode==13||h.keyCode==38||h.keyCode==40||h.keyCode==27||h.keyCode==9){h.stopPropagation();h.preventDefault()}});jQuery(this).keypress(function(h){if(h.keyCode==13||h.keyCode==38||h.keyCode==40||h.keyCode==27||h.keyCode==9){h.stopPropagation();h.preventDefault()}});jQuery(this).keyup(function(i){var h=jQuery(this).parent().find("li");var j=h.index(jQuery(this));switch(i.keyCode){case 40:h.removeClass("selected");h.eq((j+1)%h.length).addClass("selected").find("a").focus();i.stopPropagation();i.preventDefault();break;case 38:h.removeClass("selected");h.eq((j-1)%h.length).addClass("selected").find("a").focus();i.stopPropagation();i.preventDefault();break;case 13:i.stopPropagation();i.preventDefault();jQuery(this).click();break;case 27:jQuery("#qededitormenuwrapper").remove();QedEditor.buttonpanel.lastfocus.focus();i.stopPropagation();i.preventDefault();break;case 9:i.preventDefault();i.stopPropagation();default:break}})});jQuery("#qededitormenuwrapper.minus, #qededitormenuwrapper.plus").mouseleave(function(){jQuery("#qededitormenuwrapper").remove()})};function QedEditorMenuItem(a,c,b){this.operation=a;this.sdelement=c;if(typeof(b)=="undefined"){this.label="";this.label=c}else{this.label=b}}_=QedEditorMenuItem.prototype;_.html=function(){var b=["qededitormenuitem"];b.push(this.sdelement);b.push(this.operation);var c="";switch(this.operation){case"plus":c="+";break;case"minus":c="–";break;case"undo":c="↶";break;case"redo":c="↷";break;default:c=this.operation;break}var a="";testilogit.sdelement=this.sdelement;a+='<li class="'+b.join(" ")+'">\n<a href="javascript:;"><span class="menuoperation">'+c+'</span><span class="menulabel">'+QedEditor.locales[this.label][QedEditor.options.lang]+'</span><span class="menuname">'+this.sdelement+"</span></a>\n</li>\n";return a};function SdDerivation(a,b){this.editor=b;this.name="";this.task=[];this.assumption=[];this.observation=[];this.derivmotivation=[];this.term=[];this.relation=[];this.motivation=[];this.check="";this.context=a}SdDerivation.options={};SdDerivation.options.TiddlyWiki={saveTiddler:"QedDerivationsData",recycleTiddler:"QedDerivationsRecycleBin"};SdDerivation.alphatonum=function(c){var b=0;for(var a=0;a<c.length;a++){if(c.length>1&&a==0){b+=c.charCodeAt(a)-96}else{b=26*b;b+=c.charCodeAt(a)-97}}return b};SdDerivation.numtoalpha=function(b){var c=0;var a="";while(a==""||b>25){c=b%26;a=String.fromCharCode(c+97)+a;b=Math.floor(b/26)}if(b>0){c=b%26;a=String.fromCharCode(c+96)+a}return a};SdDerivation.shiftLabel=function(a,b){if(b===undefined){b=1}ll=SdDerivation.alphatonum(a);ll+=b;result=SdDerivation.numtoalpha(ll);return result};_=SdDerivation.prototype;_.name="";_.task=[];_.assumption=[];_.observation=[];_.derivmotivation=[];_.term=[];_.relation=[];_.motivation=[];_.check="";_.hidden=false;_.context="";_.init=function(j,m){var h={task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};var f=m[j];if(typeof(f)=="undefined"){f=h}this.name=j;if(f.task.length>0){var d=new SdTask(f.task[0]);this.task=[d]}else{this.task=[]}this.assumption=[];for(var k=0;k<f.assumption.length;k++){var c=new SdAssumption(f.assumption[k].label,f.assumption[k].text);this.assumption.push(c)}this.observation=[];for(var k=0;k<f.observation.length;k++){var b=new SdObservation(f.observation[k].label,f.observation[k].motivation,f.observation[k].text,this.context,this,m);this.observation.push(b)}this.derivmotivation=[];if(f.derivmotivation.length>0){var e=new SdMotivation(f.derivmotivation[0].text,f.derivmotivation[0].subderiv,false,"derivation",this.context,this,m);this.derivmotivation.push(e)}this.term=[];for(var k=0;k<f.term.length;k++){var g=new SdTerm(f.term[k].text,f.term[k].virgin);this.term.push(g)}this.relation=[];for(var k=0;k<f.relation.length;k++){var l=new SdRelation(f.relation[k].text,f.term[k].virgin);this.relation.push(l)}this.motivation=[];for(var k=0;k<f.motivation.length;k++){var a=new SdMotivation(f.motivation[k].text,f.motivation[k].subderiv,f.motivation[k].virgin,"step",this.context,this,m);this.motivation.push(a)}this.check=f.check;this.hidden=f.hidden};_.getSaveData=function(){var a={};var e=[];a.task=[];for(var c=0;c<this.task.length;c++){a.task.push(this.task[c].getSaveData())}a.assumption=[];for(var c=0;c<this.assumption.length;c++){a.assumption.push(this.assumption[c].getSaveData())}a.observation=[];for(var c=0;c<this.observation.length;c++){a.observation.push(this.observation[c].getSaveData());var d=this.observation[c].getSubSaveData();for(var b=0;b<d.length;b++){e.push(d[b])}}a.derivmotivation=[];for(var c=0;c<this.derivmotivation.length;c++){a.derivmotivation.push(this.derivmotivation[c].getSaveData());var d=this.derivmotivation[c].getSubSaveData();for(var c=0;c<d.length;c++){e.push(d[c])}}a.term=[];for(var c=0;c<this.term.length;c++){a.term.push(this.term[c].getSaveData())}a.relation=[];for(var c=0;c<this.relation.length;c++){a.relation.push(this.relation[c].getSaveData())}a.motivation=[];for(var c=0;c<this.motivation.length;c++){a.motivation.push(this.motivation[c].getSaveData());var d=this.motivation[c].getSubSaveData();for(var b=0;b<d.length;b++){e.push(d[b])}}a.check=this.check;a.hidden=this.hidden;e.push({name:this.name,data:a});return e};_.findLocation=function(d){var e=d.split("_");e.shift();var b=this;var a="";var c="";while(e.length>0){if(c=="observation"&&e[0]=="motivation"&&/^[0-9]+$/.test(e[1])){c=a;a=e.shift();e.shift()}else{c=a;a=e.shift()}b=b[a]}return b};_.addTask=function(a){if(typeof(a)=="string"){a=new SdTask(a)}this.task=[a]};_.removeTask=function(){this.task=[]};_.addStep=function(g,d){if(typeof(d)=="undefined"){var e={text:"",subderiv:[]};d={relation:"",motivation:e,term:""}}var b=(d.relation==""||d.relation==" ");var c=new SdRelation(d.relation,b);var f=new SdMotivation(d.motivation.text,d.motivation.subders,true,"step",this.context,this,{});var a=new SdTerm(d.term,true);this.term.splice(parseInt(g)+1,0,a);this.relation.splice(g,0,c);this.motivation.splice(g,0,f)};_.removeStep=function(a){this.relation.splice(a,1);this.motivation.splice(a,1);this.term.splice(parseInt(a)+1,1)};_.addAssumption=function(e,c){if(typeof(c)=="undefined"){c=""}var a=SdDerivation.numtoalpha(e);var d=new SdAssumption(a,c);for(var b=e;b<this.assumption.length;b++){this.assumption[b].shiftLabel(1)}this.assumption.splice(e,0,d)};_.removeAssumption=function(b){for(var a=b+1;a<this.assumption.length;a++){this.assumption[a].shiftLabel(-1)}this.assumption.splice(b,1)};_.addObservation=function(e,b){if(e>=this.observation.length){var a=this.observation.length+1}else{var a=this.observation[e].label}if(typeof(b)=="undefined"||b==""){var d={text:"",subderiv:[]};var b=new SdObservation(a,d,"",this.context,this,{})}for(var c=e;c<this.observation.length;c++){this.observation[c].shiftLabel(1)}this.observation.splice(e,0,b)};_.removeObservation=function(b){for(var a=b+1;a<this.observation.length;a++){this.observation[a].shiftLabel(-1)}this.observation.splice(b,1)};_.addDermot=function(a){if(typeof(a)=="undefined"){a=""}var b=new SdMotivation(a,[],true,"derivation",this.context,this,{});this.derivmotivation=[b]};_.removeDermot=function(){this.derivmotivation=[]};_.addSubderivation=function(f,h,d){if(typeof(d)=="undefined"||d==""){var e=f.split("_");d=e[0]+"sub";var c=0;var a=false;var b=10000;while(!a&&c<b){if(this.editor.derivationExists(d+c)){c++}else{a=true}}d=d+c}var g=this.findLocation(f);g.addSubderivation(d,h,this.context)};_.addSubderivationObject=function(b,d,a){var c=this.findLocation(b);c.addSubderivationObject(a,d)};_.removeSubderivation=function(c,e){var d=this.findLocation(c);var a=c.split("_")[0];var b=d.removeSubderivation(e,a);return b};_.html=function(g,f){f=(typeof(f)==="undefined")?this.name:f;var e="";var l="";if(!this.issubderivation){if(g=="edit"){}else{if(g=="showcontent"){g="show";e+='<a href="javascript:;" class="button command_qededit"></a>\n';e='<div class="qededitorbuttons">\n'+e+"</div>\n"}else{e+='\n<div class="structuredderivation" sdname="'+this.name+'">\n';e+='<a href="javascript:;" class="button command_qededit"></a>\n<div class="sdbackground">\n';e='<div class="qededitorbuttons">\n'+e+"</div>\n";l="</div>\n</div>"}}}var n=e;n+='<table class="sdtable">\n<tbody>\n';var h="";var b=["task","assumption","observation","derivmotivation"];for(var c=0;c<b.length;c++){for(var a=0;a<this[b[c]].length;a++){switch(b[c]){case"task":h={ass:(this.assumption.length>0),obs:(this.observation.length>0),dermot:(this.derivmotivation.length>0),issub:this.issubderivation};break;case"assumption":h={last:(a==this.assumption.length-1)};break;case"observation":h={};break;case"derivmotivation":h={};break;default:h={}}n+=this[b[c]][a].html(g,f+"_"+b[c]+"_"+a,h)}}if(this.term.length>0){var k=(this.term.length==1&&this.issubderivation);if(this.task.length>0){if(this.derivmotivation.length>0){n+=this.term[0].html(g,f+"_term_0",{termtype:"",last:k})}else{n+=this.term[0].html(g,f+"_term_0",{termtype:"vdash",last:k})}}else{var d=this.issubderivation;n+=this.term[0].html(g,f+"_term_0",{termtype:"bullet",last:k,first:d})}for(var c=0;c<this.motivation.length;c++){n+=this.relation[c].html(g,f+"_relation_"+c);n+=this.motivation[c].html(g,f+"_motivation_"+c);k=(c==this.motivation.length-1&&this.issubderivation);if(this.motivation[c].subderivation.length>0){n+=this.term[c+1].html(g,f+"_term_"+(c+1),{termtype:"ldots",last:k})}else{n+=this.term[c+1].html(g,f+"_term_"+(c+1),{termtype:"",last:k})}}}if(!(this.issubderivation)){var m="<tr><td>$\\square$</td><td></td></tr>";if(g=="show"||g=="edit"){m=m.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}n+=m}n+="</tbody>\n</table>\n";n+=l;return n};_.lyx=function(f){f=(typeof(f)==="undefined")?this.name:f;var e="";var k="";if(!this.issubderivation){e="";k=""}var m=e;m+='<table class="sdtable">\n<tbody>\n';var g="";var a=["task","assumption","observation","derivmotivation"];for(var c=0;c<a.length;c++){for(var b=0;b<this[a[c]].length;b++){switch(a[c]){case"task":g={ass:(this.assumption.length>0),obs:(this.observation.length>0),dermot:(this.derivmotivation.length>0),issub:this.issubderivation};break;case"assumption":g={last:(b==this.assumption.length-1)};break;case"observation":g={};break;case"derivmotivation":g={};break;default:g={}}m+=this[a[c]][b].lyx(f+"_"+a[c]+"_"+b,g)}}if(this.term.length>0){var h=(this.term.length==1&&this.issubderivation);if(this.task.length>0){if(this.derivmotivation.length>0){m+=this.term[0].lyx(f+"_term_0",{termtype:"",last:h})}else{m+=this.term[0].lyx(f+"_term_0",{termtype:"vdash",last:h})}}else{var d=this.issubderivation;m+=this.term[0].lyx(f+"_term_0",{termtype:"bullet",last:h,first:d})}for(var c=0;c<this.motivation.length;c++){m+=this.relation[c].lyx(f+"_relation_"+c);m+=this.motivation[c].lyx(f+"_motivation_"+c);h=(c==this.motivation.length-1&&this.issubderivation);if(this.motivation[c].subderivation.length>0){m+=this.term[c+1].lyx(f+"_term_"+(c+1),{termtype:"ldots",last:h})}else{m+=this.term[c+1].lyx(f+"_term_"+(c+1),{termtype:"",last:h})}}}if(!(this.issubderivation)){var l="<tr><td>$\\square$</td><td></td></tr>";m+=l}m+="</tbody>\n</table>\n";m+=k;return m};_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){var b={};b.derivations=[];var a={};a.name=this.name;a.task=[];for(var c=0;c<this.task.length;c++){a.task.push(this.task[c].jsonobject())}a.assumptions=[];for(var c=0;c<this.assumption.length;c++){a.assumptions.push(this.assumption[c].jsonobject())}a.observations=[];for(var c=0;c<this.observation.length;c++){a.observations.push(this.observation[c].jsonobject())}a.chain={};a.chain["terms"]=[];for(var c=0;c<this.term.length;c++){a.chain["terms"].push(this.term[c].jsonobject())}a.chain["relations"]=[];for(var c=0;c<this.relation.length;c++){a.chain["relations"].push(this.relation[c].jsonobject())}a.chain["motivations"]=[];for(var c=0;c<this.motivation.length;c++){a.chain["motivations"].push(this.motivation[c].jsonobject())}b.derivations.push(a);return b};_.eventDo=function(b){var a=false;switch(b.event){case"add":switch(b.item){case"task":var d=this.findLocation(b.location);d.addTask(b.newData());a=true;break;case"taskass":var d=this.findLocation(b.location);d.addTask(b.newData());d.addAssumption(0,"");if(d.term.length==1){d.term[0].text=""}a=true;break;case"taskobs":var d=this.findLocation(b.location);d.addTask(b.newData());d.addObservation(0,"");if(d.term.length==1){d.term[0].text=""}a=true;break;case"assumption":var d=this.findLocation(b.location);d.addAssumption(b.position,b.newData());a=true;break;case"observation":var d=this.findLocation(b.location);d.addObservation(b.position,b.newData());a=true;break;case"derivationmotivation":var d=this.findLocation(b.location);d.addDermot(b.newData());a=true;break;case"step":var d=this.findLocation(b.location);d.addStep(b.position,b.newData());a=true;break;case"subderivation":if(b.newData()==""){this.addSubderivation(b.location,b.position,b.newData())}else{this.addSubderivationObject(b.location,b.position,b.newData())}a=true;break;default:a=true;break}break;case"remove":switch(b.item){case"task":var d=this.findLocation(b.location);d.removeTask();a=true;break;case"taskass":var d=this.findLocation(b.location);d.removeTask();d.removeAssumption(0);if(d.term.length==1){d.term[0].text=b.newData()}a=true;break;case"taskobs":var d=this.findLocation(b.location);d.removeTask();d.removeObservation(0);if(d.term.length==1){d.term[0].text=b.newData()}a=true;break;case"assumption":var d=this.findLocation(b.location);d.removeAssumption(b.position);a=true;break;case"observation":var d=this.findLocation(b.location);d.removeObservation(b.position);a=true;break;case"derivationmotivation":var d=this.findLocation(b.location);d.removeDermot();a=true;break;case"step":var d=this.findLocation(b.location);d.removeStep(b.position);a=true;break;case"subderivation":a=this.removeSubderivation(b.location,b.position);break;default:a=true;break}break;case"edit":var c=this.findLocation(b.location);if(typeof(c.virgin)!="undefined"&&c.virgin){c.virgin=false}c.text=b.newData();a=true;break;default:break;a=true}return a};function SdSubDeriv(d,a,c,b){if(typeof(b)=="undefined"){var b={}}this.editor=c;this.name="";this.task=[];this.assumption=[];this.observation=[];this.derivmotivation=[];this.term=[];this.relation=[];this.motivation=[];this.check="";this.hidden=false;this.issubderivation=true;this.context=a;this.init(d,b)}_=SdSubDeriv.prototype=new SdDerivation;_.htmlSub=function(d,c){var a=this.html(d,c);var b="sdsubderivation";if(this.hidden){b+=" sdhiddensub"}a='\n\n\n<div class="'+b+'">\n'+a+"</div>\n\n\n";return a};_.lyxSub=function(b){var a=this.lyx(b);a='\n\n\n<div class="">\n'+a+"</div>\n\n\n";return a};function SdTask(a){this.text=a}_=SdTask.prototype;_.text="";_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){return this.text};_.html=function(g,d,h){var a="$\\bullet$";var c="";var f="";var i=[];var e=[];if(!(h===undefined)){if(!(h.ass||h.obs||h.dermot)){i.push("task")}if(h.ass){e.push("assumption")}else{e.push("assumption");e.push("observation")}if(h.issub){i.push("subderivation")}if(i.length>0){c='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>'}if(e.length>0){f='<a href="javascript:;" class="sdaddbutton""><span>+</span></a>'}}i='<span class="minusbuttons" menuitems="'+i.join(" ")+'"></span>';e='<span class="plusbuttons" menuitems="'+e.join(" ")+'"></span>';c='<div class="sdbeforebuttons">'+i+c+"</div>";f='<div class="sdafterbuttons">'+e+f+"</div>";var b=["task"];if(g=="show"||g=="edit"){a=a.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>');addbuttons=""}var j=this.text;if(g=="show"){j=j.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(g=="edit"){j='<span class="mathquill-textbox">'+j+"</span>"}}j='<tr><td class="bullet">'+c+a+'</td><td class="'+b.join(" ")+'" loc="'+d+'">'+j+f+"</td></tr>\n";return j};_.lyx=function(d,c){var b="$\\bullet$";var a=this.text;a='<tr><td class="bullet">'+b+'</td><td class= loc="'+d+'">'+a+"</td></tr>\n";return a};_.getSaveData=function(){return this.text};function SdAssumption(a,b){this.label=a;this.text=b;this.virgin=false;if(b==""){this.virgin=true}}_=SdAssumption.prototype;_.label="";_.text="";_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){return[this.label,this.text]};_.shiftLabel=function(a){if(a===undefined){a=1}this.label=SdDerivation.shiftLabel(this.label,a)};_.html=function(f,c,g){var i=this.text;var h=[];var d=[];h.push("assumption");d.push("assumption");if(!(g===undefined)){if(g.last){e+='<a href="javascript:;" class="addobservation sdaddbutton" title="add observation"><span>[+]</span></a>';d.push("observation")}}var b='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>';var e='<a href="javascript:;" class="sdaddbutton"><span>+</span></a>';h='<span class="minusbuttons" menuitems="'+h.join(" ")+'"></span>';d='<span class="plusbuttons" menuitems="'+d.join(" ")+'"></span>';b='<div class="sdbeforebuttons">'+h+b+"</div>";e='<div class="sdafterbuttons">'+d+e+"</div>";if(f=="show"){i=i.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(f=="edit"){i='<span class="mathquill-textbox">'+i+"</span>"}}var a=this.virgin?" virgin":"";i="<tr><td>"+b+"("+this.label+')</td><td class="assumption'+a+'" loc="'+c+'">'+i+e+"</td></tr>\n";return i};_.lyx=function(c,b){var a=this.text;a='<span class="mathquill-textbox">'+a+"</span>";a="<tr><td>("+this.label+')</td><td class="assumption" loc="'+c+'">'+a+"</td></tr>\n";return a};_.getSaveData=function(){return{label:this.label,text:this.text}};function SdObservation(c,g,b,d,f,e){if(g===undefined){g={text:"",subderiv:[]}}if(b===undefined){b=""}if(d===undefined){d=""}var a=false;if(g.text==""){a=true}this.virgin=false;if(b==""){this.virgin=true}this.parent=f;this.label=c;this.motivation=new SdMotivation(g.text,g.subderiv,a,"observation",d,this.parent,e);this.text=b}_=SdObservation.prototype;_.label="";_.motivation=new SdMotivation;_.text="";_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){return[this.label,this.motivation.jsonobject(),this.text]};_.shiftLabel=function(a){if(a===undefined){a=1}this.label=this.label+a};_.html=function(f,c,g){if(g===undefined){g={}}var h=[];var d=[];var b="";var e="";var l=this.motivation.html(f,c+"_motivation");h.push("observation");d.push("observation");var b='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>';var e='<a href="javascript:;" class="sdaddbutton"><span>+</span></a>';h='<span class="minusbuttons" menuitems="'+h.join(" ")+'"></span>';d='<span class="plusbuttons" menuitems="'+d.join(" ")+'"></span>';b='<div class="sdbeforebuttons">'+h+b+"</div>";e='<div class="sdafterbuttons">'+d+e+"</div>";l="<tr><td>"+b+"["+this.label+"]</td>"+l+"</tr>\n";var a="";var k="";if(this.motivation.subderivation.length>0){a='<span class="mathquill-embedded-latex">\\ldots</span>';k="ldots"}var j=this.text;if(f=="show"){j=j.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(f=="edit"){j='<span class="mathquill-textbox">'+j+"</span>"}}var i=this.virgin?" virgin":"";j='<tr><td class="'+k+'">'+a+'</td><td class="observation'+i+'" loc="'+c+'">'+j+e+"</td></tr>\n";var m=l+j;return m};_.lyx=function(f,b){if(b===undefined){b={}}var e=this.motivation.html(editmode,f+"_motivation");e="<tr><td>"+beforebuttons+"["+this.label+"]</td>"+e+"</tr>\n";var c="";if(this.motivation.subderivation.length>0){c='<span class="mathquill-embedded-latex">\\ldots</span>'}var d=this.text;d='<span class="mathquill-textbox">'+d+"</span>";d='<tr><td class="'+tdclass+'">'+c+'</td><td class="observation'+obsclass+'" loc="'+f+'">'+d+afterbuttons+"</td></tr>\n";var a=e+d;return a};_.getSubSaveData=function(){return this.motivation.getSubSaveData()};_.getSaveData=function(){return{label:this.label,motivation:this.motivation.getSaveData(),text:this.text,virgin:this.virgin}};function SdTerm(b,a){this.text=b;if(typeof(a)=="undefined"){a=false}this.virgin=a}_=SdTerm.prototype;_.text="";_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){return"$"+this.text+"$"};_.html=function(g,d,h){if(h===undefined){h={termtype:""}}var b=[];if(this.virgin){b.push("virgin")}b.push("term");var j="";var c="";var f="";var a="";var i=[];var e=[];if(h.termtype=="bullet"){j="$\\bullet$";e.push("task");e.push("taskass");e.push("taskobs");if(h.first){i.push("subderivation")}}else{if(h.termtype=="vdash"){j="$\\Vdash$";e.push("derivationmotivation")}else{if(h.termtype=="ldots"){j="$\\ldots$"}}}if(g=="show"||g=="edit"){j=j.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}var k="$ "+this.text+"$";if(g=="show"){k=k.replace(/\$([^\$]*)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(g=="edit"){k=k.replace(/\$([^\$]*)\$/g,'<span class="mathquill-editable">$1</span>');e.push("step")}}if(h.last){e.push("subderivation")}if(i.length>0){c='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>'}if(e.length>0){f='<a href="javascript:;" class="sdaddbutton"><span>+</span></a>'}i='<span class="minusbuttons" menuitems="'+i.join(" ")+'"></span>';e='<span class="plusbuttons" menuitems="'+e.join(" ")+'"></span>';c='<div class="sdbeforebuttons">'+i+c+"</div>";f='<div class="sdafterbuttons">'+e+f+"</div>";k='<tr><td class="'+h.termtype+'">'+c+j+'</td><td class="'+b.join(" ")+'" loc="'+d+'">'+k+a+f+"</td></tr>\n";return k};_.lyx=function(d,c){if(c===undefined){c={termtype:""}}var b="";if(c.termtype=="bullet"){b="$\\bullet$"}else{if(c.termtype=="vdash"){b="$\\Vdash$"}else{if(c.termtype=="ldots"){b="$\\ldots$"}}}var a="$ "+this.text+"$";a='<tr><td class="'+c.termtype+'">'+b+'</td><td class="'+tdclasses.join(" ")+'" loc="'+d+'">'+a+"</td></tr>\n";return a};_.getSaveData=function(){return{text:this.text,virgin:this.virgin}};function SdRelation(a,b){this.text=a;if(typeof(b)=="undefined"){b=false}this.virgin=b}_=SdRelation.prototype;_.text="";_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){return"$"+this.text+"$"};_.html=function(h,g,d){if(d===undefined){d={}}var e=[];var f="";var c="";var b=[];if(this.text!=""){this.virgin=false}if(this.virgin){e.push("virgin")}e.push("relation");var a="$ "+this.text+"$";if(h=="show"){a=a.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(h=="edit"){a=a.replace(/\$([^\$]+)\$/g,'<span class="mathquill-editable">$1</span>');b.push("step")}}if(b.length>0){f+='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>'}b='<span class="minusbuttons" menuitems="'+b.join(" ")+'"></span>';f='<div class="sdbeforebuttons">'+b+f+"</div>";a='<tr><td class="'+e.join(" ")+'" loc="'+g+'">'+f+a+"</td>\n";return a};_.lyx=function(c,b){if(b===undefined){b={}}var a="$ "+this.text+"$";a='<tr><td class="" loc="'+c+'">'+a+"</td>\n";return a};_.getSaveData=function(){return{text:this.text,virgin:this.virgin}};function SdMotivation(c,h,d,f,a,g,j){this.parent=g;this.text=c;this.subderivation=[];this.mottype=f;if(typeof(d)=="undefined"){d=false}this.virgin=d;if(!(h===undefined)&&!!h){for(var e=0;e<h.length;e++){var b=new SdSubDeriv(h[e],a,this.parent.editor,j);this.subderivation.push(b)}}}_=SdMotivation.prototype;_.text="";_.subderivation=[];_.json=function(){return JSON.stringify(this.jsonobject())};_.jsonobject=function(){var a=[this.text];for(var b=0;b<this.subderivation.length;b++){a.push(this.subderivation[b].jsonobject())}return a};_.html=function(l,g,m){if(m===undefined){m={}}var c=[];var e="";var k="";var n=[];var j=[];if(this.virgin){c.push("virgin")}var h="motivation";var b="";if(this.mottype=="observation"){h="obsmotivation"}else{if(this.mottype=="derivation"){n.push("derivationmotivation");e='<a href="javascript:;" class="sdremovebutton"><span>–</span></a>';n='<span class="minusbuttons" menuitems="'+n.join(" ")+'"></span>';e='<div class="sdbeforebuttons">'+n+e+"</div>";b="<tr><td>"+e+'<span class="mathquill-embedded-latex">\\Vdash </span></td>';h="derivmotivation"}}if(this.mottype=="step"||this.mottype=="observation"){j.push("subderivation");k='<a href="javascript:;" class="sdaddbutton"><span>+</span></a>';j='<span class="plusbuttons" menuitems="'+j.join(" ")+'"></span>';k='<div class="sdafterbuttons">'+j+k+"</div>"}c.push(h);var o=this.text;var a="";var f=false;if(l=="show"){o=o.replace(/\$([^\$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>')}else{if(l=="edit"){o='<span class="mathquill-textbox">'+o+"</span>"}}o=b+'<td class="'+c.join(" ")+'" loc="'+g+'"><span class="motivationstring">'+o+"</span>"+k+"</td>";for(var d=0;d<this.subderivation.length;d++){f=f||this.subderivation[d].hidden}if(f){a="sdhidden"}for(var d=0;d<this.subderivation.length;d++){o+='</tr>\n<tr class="'+a+'"><td class="subder"></td><td class="subderivation" loc="'+g+"_subderivation_"+d+'">';o+=this.subderivation[d].htmlSub(l,g+"_subderivation_"+d);o+="\n</td>\n"}o+="</tr>\n";return o};_.lyx=function(e,c){if(c===undefined){c={}}var b="";if(this.mottype=="observation"){className="obsmotivation"}else{if(this.mottype=="derivation"){b="<tr><td>⊩</td>";className="derivmotivation"}}tdclasses.push(className);var a=this.text;a='<span class="mathquill-textbox">'+a+"</span>";a=b+'<td class="'+tdclasses.join(" ")+'" loc="'+e+'"><span class="motivationstring">'+a+"</span></td>";for(var d=0;d<this.subderivation.length;d++){a+='</tr>\n<tr class=""><td class="subder"></td><td class="subderivation" loc="'+e+"_subderivation_"+d+'">';a+=this.subderivation[d].lyxSub(e+"_subderivation_"+d);a+="\n</td>\n"}a+="</tr>\n";return a};_.getSaveData=function(){var b=[];for(var a=0;a<this.subderivation.length;a++){b.push(this.subderivation[a].name)}return{text:this.text,subderiv:b,virgin:this.virgin}};_.getSubSaveData=function(){var d=[];for(var c=0;c<this.subderivation.length;c++){var a=this.subderivation[c].getSaveData();for(var b=0;b<a.length;b++){d.push(a[b])}}return d};_.addSubderivation=function(b,e,c,d){if(typeof(b)!="string"||b==""){return}if(c===undefined){c=""}var a=new SdSubDeriv(b,c,d);this.subderivation.splice(e,0,a)};_.addSubderivationObject=function(a,b){this.subderivation.splice(b,0,a)};_.removeSubderivation=function(g,a){var d=this.subderivation[g];var f=[d.name];for(var c=0;c<d.observation.length;c++){for(var b=0;b<d.observation[c].motivation.subderivation.length;b++){var e=d.observation[c].motivation.removeSubderivation(b,a);f=f.concat(e)}}for(var c=0;c<d.motivation.length;c++){for(var b=0;b<d.motivation[c].subderivation.length;b++){var e=d.motivation[c].removeSubderivation(b,a);f=f.concat(e)}}this.subderivation.splice(g,1);return f};_.hideSubders=function(){for(var a=0;a<this.subderivation.length;a++){this.subderivation[a].hidden=true}};_.unhideSubders=function(){for(var a=0;a<this.subderivation.length;a++){this.subderivation[a].hidden=false}};_.switchHideSubders=function(){var a=false;for(var b=0;b<this.subderivation.length;b++){a=a||this.subderivation[b].hidden}if(a){this.unhideSubders()}else{this.hideSubders()}};function ButtonPanel(c){if(c===undefined){c=defbuttons}this.buttontables=[];if(c!=[]){for(var b=0;b<c.length;b++){table=new ButtonTable(c[b].name,c[b].icon);for(var a=0;a<c[b].elements.length;a++){element=new ButtonElement(c[b].elements[a].name,c[b].elements[a].latex,c[b].elements[a].icon,c[b].elements[a].inside,c[b].elements[a].move);table.addElement(element)}this.buttontables.push(table)}}this.lastfocus=""}_=ButtonPanel.prototype;_.createpanel=function(c){this.buttontables=[];if(c!=[]){for(var b=0;b<c.length;b++){table=new ButtonTable(c[b].name,c[b].icon);for(var a=0;a<c[b].elements.length;a++){element=new ButtonElement(c[b].elements[a].name,c[b].elements[a].latex,c[b].elements[a].icon);table.addElement(element)}this.buttontables.push(table)}}};_.addTable=function(a){this.buttontables.push(a)};_.html=function(){var a="";a+='<div id="mathbuttonpanel">\n';if(this.buttontables!=[]){a+=' <ul class="buttontablelist">\n';for(var b=0;b<this.buttontables.length;b++){a+=' <li class="buttontableicon">\n <a href="javascript:;" class="'+this.buttontables[b].name+'"><span class="buttonicon">'+this.buttontables[b].icon+'</span><span class="buttoncategoryname">'+QedEditor.locales[this.buttontables[b].name][QedEditor.options.lang]+'</span></a>\n<div class="buttoncatwrapper">\n';a+=this.buttontables[b].html();a+=" </div></li>\n"}a+=" </ul>\n"}a+="</div>\n";return a};_.initClicks=function(){jQuery("#mathbuttonpanel .buttonelementtable a.buttonlink").click(function(){var f=jQuery(this).attr("title");var b=jQuery(this).attr("inside");var a=jQuery(QedEditor.buttonpanel.lastfocus);if(a.focus().find(".cursor").parent().hasClass("text")||a.focus().find(".cursor").parent().hasClass("mathquill-textbox")){return false}var e=a.data("[[mathquill internal data]]");var h=e&&e.block;var g=h&&h.cursor;var d="";if(g&&g.selection){var d=g.selection.latex()}if(d!=""){if(b=="1"){a.mathquill("write",f+"{"+g.selection.latex()+"}")}else{if(b=="2"){a.mathquill("write",f+"{"+g.selection.latex()+"}{}")}else{a.mathquill("write",f)}}}else{a.mathquill("write",f)}a.focus();if(g){for(var c=0;c<parseInt(b);c++){g.moveLeft()}}return false})};function ButtonTable(a,b){this.name=a;this.icon=b;this.buttonelements=[]}_=ButtonTable.prototype;_.html=function(){var b=this.buttonelements.length;var a="";if(b==0){return""}else{var c=Math.ceil(Math.sqrt(b));a+=' <table class="buttonelementtable">\n';for(var e=0;c*e<b;e++){a+=" <tr>\n";for(var d=0;d<c;d++){if(c*e+d<b){a+=' <td> <a class="buttonlink '+this.buttonelements[c*e+d].name+'" href="javascript:;" title="'+this.buttonelements[c*e+d].latex+'" inside="'+this.buttonelements[c*e+d].has_inside+'" ><span>'+this.buttonelements[c*e+d].icon+"</span></a></td>\n"}else{a+="<td></td>"}}a+=" </tr>\n"}a+=" </table>\n"}return a};_.addElement=function(a){this.buttonelements.push(a)};function ButtonElement(b,d,c,a){this.name=b;this.latex=d;this.icon=c;if(a===undefined){a=0}this.has_inside=a}var defbuttons=[{name:"relations",icon:"R",elements:[{name:"equal",latex:"= ",icon:"="},{name:"lessthan",latex:"\\lt ",icon:"<"},{name:"greaterthan",latex:"\\gt ",icon:">"},{name:"lessorequalthan",latex:"\\leq ",icon:"≤"},{name:"greaterorequalthan",latex:"\\geq ",icon:"≥"},{name:"notequal",latex:"\\neq ",icon:"≠"},{name:"leftimp",latex:"\\Leftarrow ",icon:"⇐"},{name:"rightimp",latex:"\\Rightarrow ",icon:"⇒"},{name:"eqvivalent",latex:"\\iff ",icon:"⇔"}]},{name:"misc",icon:"M",elements:[{name:"frac",latex:"\\frac ",icon:"/",inside:"2"},{name:"sqroot",latex:"\\sqrt ",icon:"√",inside:"1"},{name:"sub",latex:"_",icon:'X<sub style="color: red; font-weight: bold;">2</sub>',inside:"1"},{name:"sup",latex:"^",icon:'X<sup style="color: red; font-weight: bold;">2</sup>',inside:"1"},{name:"isin",latex:"\\in ",icon:"∈"},{name:"logicalor",latex:"\\lor ",icon:"∨"},{name:"logicaland",latex:"\\and ",icon:"∧"},{name:"logicalnot",latex:"\\not ",icon:"¬"},{name:"infinity",latex:"\\inf ",icon:"∞"},{name:"empty",latex:"\\emptyset ",icon:"∅"},{name:"angle",latex:"\\angle ",icon:"∠"},{name:"degree",latex:"^{\\circ } ",icon:"°"},{name:"approx",latex:"\\approx ",icon:"≈"},{name:"plusminus",latex:"\\pm ",icon:"±"}]},{name:"greeks",icon:"α",elements:[{name:"alpha",latex:"\\alpha ",icon:"α"},{name:"beta",latex:"\\beta ",icon:"β"},{name:"gamma",latex:"\\gamma ",icon:"γ"},{name:"delta",latex:"\\delta ",icon:"δ"},{name:"epsilon",latex:"\\epsilon ",icon:"ε"},{name:"zeta",latex:"\\zeta ",icon:"ζ"},{name:"eta",latex:"\\eta ",icon:"η"},{name:"theta",latex:"\\theta ",icon:"θ"},{name:"iota",latex:"\\iota ",icon:"ι"},{name:"kappa",latex:"\\kappa ",icon:"κ"},{name:"lambda",latex:"\\lambda ",icon:"λ"},{name:"mu",latex:"\\mu ",icon:"μ"},{name:"nu",latex:"\\nu ",icon:"ν"},{name:"xi",latex:"\\xi ",icon:"ξ"},{name:"pi",latex:"\\pi ",icon:"π"},{name:"rho",latex:"\\rho ",icon:"ρ"},{name:"sigma",latex:"\\sigma ",icon:"σ"},{name:"tau",latex:"\\tau ",icon:"τ"},{name:"upsilon",latex:"\\upsilon ",icon:"υ"},{name:"phi",latex:"\\phi ",icon:"φ"},{name:"chi",latex:"\\chi ",icon:"χ"},{name:"psi",latex:"\\psi ",icon:"ψ"},{name:"omega",latex:"\\omega ",icon:"ω"}]}];QedEditor.buttonpanel=new ButtonPanel();function EditorEvent(b,a,d,e,c){if(typeof(b)=="string"){this.event=b;if(typeof(a)=="undefined"){this.item=""}else{this.item=a}if(typeof(d)=="undefined"){this.location=""}else{this.location=d}if(typeof(e)=="undefined"){this.position=-1}else{this.position=parseInt(e)}if(typeof(c)=="undefined"){this.data=["",""]}else{this.data=c}}else{this.event=b.event;this.item=b.item;this.location=b.location;this.position=b.position;this.data=[b.data[0],b.data[1]]}}_=EditorEvent.prototype;_.oldData=function(){return this.data[1]};_.newData=function(){return this.data[0]};_.invertThis=function(){switch(this.event){case"edit":this.data.reverse();break;case"add":this.event="remove";this.data.reverse();break;case"remove":this.event="add";this.data.reverse();break;default:return this}};_.invert=function(){var a=new EditorEvent(this);a.invertThis();return a};function Eventstack(b,a){if(typeof(a)=="object"&&a.length){this.stackevents=a}else{this.stackevents=[]}this.maxstacksize=b}_=Eventstack.prototype;_.maxsize=function(a){if(typeof(a)=="number"){this.maxstacksize=a}else{return this.maxstacksize}};_.push=function(a){this.stackevents.push(a);if(this.stackevents.length>this.maxstacksize&&this.maxstacksize>0){this.stackevents.shift()}};_.pop=function(){return this.stackevents.pop()};_.clear=function(){this.stackevents=[]};_.size=function(){return this.stackevents.length};_.isempty=function(){return this.stackevents.length==0};function QedPlugin(a,d,c,b){this.editor=b||false;this.name=a;this.iconurl=d;this.buttons=[];this.data={};this.init=c||function(){return false}}_=QedPlugin.prototype;_.html=function(){var b='<div class="pluginbuttons" name="'+this.name+'">\n<span class="pluginname"><img src="'+this.iconurl+'" alt="'+this.name+'" style="height: 24px; width: auto;" /></span><ul>\n';for(var a=0;a<this.buttons.length;a++){b+=this.buttons[a].html()}b+="</ul>\n</div>\n";return b};_.setData=function(a){this.data=a};_.use=function(b){if(typeof(b)=="undefined"){b=this.editor}var d=new QedPlugin(this.name,this.iconurl,this.init,b);var c;for(var a=0;a<this.buttons.length;a++){d.buttons.push(this.buttons[a].use(this))}return d};_.addButton=function(a){a.plugin=this;this.buttons.push(a)};_.savedata=function(b,a){if(typeof(b)!="string"){return false}switch(this.editor.context){case"tiddlywiki":var c=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.editor.extraparams.tiddler)!="undefined"){c=this.editor.extraparams.tiddler}this.saveTiddly(c,b,a);break;case"moodlesa":this.saveMoodleSA(b,a);break;case"moodledesc":break;default:return"Invalid context!"}};_.saveTiddly=function(c,b,a){var e=this.editor.derivation.name;var d=DataTiddler.getData(c,"derivations",{});if(typeof(d[e].plugindata)=="undefined"){d[e].plugindata={}}if(typeof(d[e].plugindata[this.name])=="undefined"){d[e].plugindata[this.name]={}}if(typeof(a)!="undefined"){d[e].plugindata[this.name][b]=a}else{delete d[e].plugindata[this.name][b]}DataTiddler.setData(c,"derivations",d)};_.saveMoodleSA=function(h,f){var a=this.editor.derivation.name;var c=a.replace(/sub[0-9]+$/,"");var b=jQuery("#"+c+' .ablock input[type="text"]');var e=b.val();var k="{}";try{k=JSON.parse(e)}catch(g){k={derivations:{},recycled:{}}}if(typeof(k.derivations)=="undefined"){k.derivations={}}if(typeof(k.derivations[a].plugindata)=="undefined"){k.derivations[a].plugindata={}}if(typeof(k.derivations[a].plugindata[this.name])=="undefined"){k.derivations[a].plugindata[this.name]={}}if(typeof(f)!="undefined"){k.derivations[a].plugindata[this.name][h]=f}else{delete k.derivations[a].plugindata[this.name][h]}e=JSON.stringify(k);b.val(e);if(this.saveajax){var d=$("form#responseform").attr("action")+"#"+c;var j=jQuery('<div class="ajaxanswer"></div>');var i={};i["resp"+c.slice(1)+"_"]=e;i["resp"+c.slice(1)+"_submit"]="Submit";i.timeup=0;i.questionids=c.slice(1);testilogit.ajaxresponse=jQuery.post(d,i)}};_.getdata=function(a){if(typeof(a)!="string"){return false}switch(this.editor.context){case"tiddlywiki":var b=QedEditor.options.TiddlyWiki.saveTiddler;if(typeof(this.editor.extraparams.tiddler)!="undefined"){b=this.editor.extraparams.tiddler}return this.getdataTiddly(b,a);break;case"moodlesa":return this.getdataMoodleSA(a);break;case"moodledesc":break;default:return"Invalid context!"}};_.getdataTiddly=function(e,c){var g=this.editor.derivation.name;var f,a;var b={};b[g]={task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};var d=DataTiddler.getData(e,"derivations",b);if(typeof(d[g])=="undefined"){f=b[g]}else{f=d[g]}if(typeof(f.plugindata)=="undefined"){a={}}else{a=f.plugindata}if(typeof(a[this.name])=="undefined"){a={}}else{a=a[this.name]}return a[c]};_.getdataMoodleSA=function(h){var a=this.editor.derivation.name;var d,g;var c=this.editor.name;var b=jQuery("#"+c+' .ablock input[type="text"]');var e=b.val();var i="{}";try{i=JSON.parse(e)}catch(f){i={derivations:{},recycled:{}}}if(typeof(i.derivations)=="undefined"){i.derivations={}}var d=(typeof(i.derivations[a])!="undefined")?i.derivations[a]:{task:[],assumption:[],observation:[],derivmotivation:[],term:[{text:"",virgin:false}],relation:[],motivation:[],check:""};if(typeof(d.plugindata)=="undefined"){g={}}else{g=d.plugindata}if(typeof(g[this.name])=="undefined"){g={}}else{g=g[this.name]}return g[h]};function QedPluginButton(a,d,c,b){this.plugin=b||false;this.name=a;this.iconurl=d;this.action=c||function(){alert(this.name)}}_=QedPluginButton.prototype;_.html=function(){var a='<li class="pluginitem"><a href="javascript:" class="pluginbutton"><span><img src="'+this.iconurl+'" alt="'+this.name+'" style="height: 24px; width: auto;" />'+this.name+"</span></a></li>\n";return a};_.use=function(b){if(typeof(b)=="undefined"){b=this.plugin}var a=new QedPluginButton(this.name,this.iconurl,this.action,b);return a};QedEditor.plugins=[];QedEditor.plugindata={};QedEditor.addPlugin=function(c){var a=-1;for(var b=0;b<QedEditor.plugindata.plugins.length;b++){if(QedEditor.plugindata.plugins[b].name==c.name){a=b;break}}if(a!=-1&&typeof(c)!="undefined"){QedEditor.plugins[a]=c}};
/***
|''Name:''|Emathbook.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Emathbookshelf for E-math ebook|
|''Version:''|1.1|
|''Date:''|November 2, 2012|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131003.12.02 ''added feature''
* Close button for pageTwo apps.
<<<
<<<
20130917.11.29 ''added feature''
* If there are no books, open a dummy empty book without errors.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/************************************************************************
* Emathbookshelf -class
* Holds the list of available books and apps.
* Available book tocs are found from tiddlers tagged with 'ebooktoc'.
* Available book apps should be found from tiddlers tagged with 'ebookapps'. TODO!
************************************************************************/
Emathbookshelf = function(){
this.init();
}
Emathbookshelf.prototype.init = function(){
this.appsAvailable = [];
var appdataTiddlers = store.getTaggedTiddlers('ebookappsdata');
for (var i=0; i < appdataTiddlers.length;i++){
this.appsAvailable = this.appsAvailable.concat(DataTiddler.getData(appdataTiddlers[i], 'ebookapps', []));
}
this.booksAvailable = {};
this.bookLangs = {};
var tocs = store.getTaggedTiddlers('ebooktoc');
for (var i = 0; i < tocs.length; i++){
var book = DataTiddler.getData(tocs[i].title, 'booktoc', {});
if (book.bookid){
this.booksAvailable[book.bookid] = book.title;
this.bookLangs[book.bookid] = (book.lang ? [book.lang] : []);
this.bookLangs[book.bookid] = this.bookLangs[book.bookid].concat(book.altlangs || []);
}
}
this.books = {}
}
Emathbookshelf.prototype.getAvailableBooksIds = function(){
// Returns an array of chapid:s of available books
var bookidlist = []
for (bookid in this.booksAvailable){
bookidlist.push(bookid);
}
bookidlist.sort(function(a,b){return parseInt(a) - parseInt(b)});
return bookidlist;
}
Emathbookshelf.prototype.getAvailableBooksTitle = function(){
// Returns an array of titles of available books
var titlelist = []
for (bookid in this.booksAvailable){
titlelist.push(this.booksAvailable[bookid]);
}
return titlelist;
}
Emathbookshelf.prototype.getBook = function(bookid){
// Get selected book (Emathbook-object) from bookshelf
if (!this.booksAvailable[bookid]){
var firstBook = this.getAvailableBooksIds()[0];
if (firstBook){
return this.getBook(firstBook);
} else {
var emptybook = new Emathbook();
emptybook.init({"bookid":"emptybook","title":"Empty book","alttitles":{},"curriculum":"none","lang":"none","altlangs":[],"author":[],"secondaryauthor":[],"updateURL":"","style":"coursebook hidesub","frontpage":{"title":EbookDictionary.localize('no books available'),"types":["front"],"chapid":"front","content":"noBooks","chapters":[]}});
return emptybook;
}
// return false;
}
if (!this.books[bookid]){
if (store.tiddlerExists(bookid + '_toc')){
var toc = DataTiddler.getData(bookid + '_toc', 'booktoc', {"bookid": bookid, "title": '', "alttitles": {}, "curriculum":"", "lang":"", "altlangs":[], "updateURL":"", "style": ""});
}
this.books[bookid] = new Emathbook();
this.books[bookid].init(toc);
}
return this.books[bookid];
}
Emathbookshelf.prototype.getBookTitle = function(bookid){
// Get title of book with id bookid.
return this.booksAvailable[bookid];
}
Emathbookshelf.prototype.getHtml = function(page){
// Get list of books as html
page = page || 0;
var pagelist = ['pageOne','pageTwo'];
var htmlbefore = '<ul class="bookshelf">\n';
var htmlafter = '</ul>\n';
var html = '';
var books = this.getAvailableBooksIds();
if (books.length == 0){
return false;
}
for (var i = 0; i < books.length; i++){
var imagename = 'bookicon_'+books[i]+'.png';
if (!store.tiddlerExists(imagename)){
imagename = 'bookicon_default.png';
}
var booklist = '';
for (var j = 0; j < this.bookLangs[books[i]].length; j++){
var classes = ['booklang'];
if (typeof(Emathbook.options.user.ebookpages[pagelist[page]][books[i]]) != 'undefined'){
var lang = Emathbook.options.user.ebookpages[pagelist[page]][books[i]].lang;
} else {
var lang = this.bookLangs[books[i]][0];
Emathbook.options.user.ebookpages[pagelist[page]][books[i]] = {"lang": lang};
}
if (this.bookLangs[books[i]][j] == lang){
classes.push('currentlang');
}
booklist += '<li class="'+classes.join(' ')+'"><span>'+this.bookLangs[books[i]][j]+'</span></li>';
}
var imagestring = wikifyStatic('[img['+imagename+']]');
html += ' <li class="bookshelfitem" bookid="'+books[i]+'"><a href="javascript:;">'+imagestring+'<p><span>'+this.getBookTitle(books[i])+'</span></p><ul class="bookitemlangs">'+booklist+'</ul></a></li>\n';
}
return htmlbefore + html + htmlafter;
}
Emathbookshelf.prototype.getAppsHtml = function(){
// Get list of apps as html
var htmlbefore = '<ul class="applist">\n';
var htmlafter = '</ul>\n';
var html = '';
if (this.appsAvailable.length == 0){
return false;
}
for (var i = 0; i < this.appsAvailable.length; i++){
var app = this.appsAvailable[i];
var imagename = this.appsAvailable[i].icon;
var imagestring = ' ';
if (app.iconsvg) {
imagestring = app.iconsvg;
} else if (store.tiddlerExists(imagename)){
imagestring = wikifyStatic('[img['+app.name+'|'+imagename+']]');
}
var closebutton = (app.showclosebutton ? ' data-closebutton="true"' : '');
if (store.tiddlerExists(this.appsAvailable[i].content)){
html += ' <li class="applistitem" appname="'+this.appsAvailable[i].name+'" content="'+this.appsAvailable[i].content+'" refresh="'+(this.appsAvailable[i].refresh ? 1 : 0)+'" openpage="'+(this.appsAvailable[i].openpage ? this.appsAvailable[i].openpage : '')+'"'+closebutton+'><a href="javascript:;">'+imagestring+'</a></li>\n';
}
}
return htmlbefore + html + htmlafter;
}
//}}}
/***
|''Name:''|Emathbook.js(2)|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|EmathbookPage for E-math ebook|
|''Version:''|1.3|
|''Date:''|November 2, 2012|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131112.15.47 ''fix'' ''version 1.3''
* fixed teacherelements show
<<<
<<<
20131010.12.32 ''add'' ''version 1.2''
* Added isAssignmentPage(), is<Type>Page(), hasType(), getTypes()
* Added setModelsolutions()
<<<
<<<
20130913.10.37 ''change''
* Change getElementNumber() so that numbers are counted only once.
<<<
<<<
20130913.10.37 ''fix''
* Set teacher elements with twopage mode with next page.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/************************************************************************
* EmathbookPage -class
* Class to hold data of visible pages in tiddlybook. (currently two of them)
************************************************************************/
EmathbookPage = function(pagename, ebook){
this.page = pagename;
this.pagenum = (pagename == 'pageOne' ? 0 : (pagename == 'pageTwo' ? 1 : null));
this.ebook = ebook;
this.currentpage = '';
}
EmathbookPage.config = {
"datatiddler": "SettingsEbook",
"userdatatiddler": "SettingsEbookUser"
// "datatiddler": "EmathbookSettings"
}
EmathbookPage.prototype.setBook = function(ebook){
// Set the ebook of this page.
this.ebook = ebook;
this.getSettings();
// TODO! is this unused? (see .getSettings())
if (!this.currentpage || this.currentpage == ''){
this.currentpage = this.ebook.frontId();
}
Emathbook.options.pages[this.pagenum].lang = this.currentlang || '';
Emathbook.options.pages[this.pagenum].defaultlang = this.ebook.defaultlang || '';
Emathbook.options.pages[this.pagenum].curriculum = this.ebook.curriculum || '';
this.setPage(this.currentpage);
jQuery('#'+this.page).attr('lang',this.currentlang).attr('curriculum',this.ebook.curriculum || '');
}
EmathbookPage.prototype.changeBook = function(ebook){
// Change the ebook of this page and refresh the navibar.
this.setBook(ebook);
Emathbook.options.saveUserSettingsLocal();
refreshElements(jQuery('#'+this.page+'Wrapper')[0], [this.page+'Navi']);
}
EmathbookPage.prototype.initBook = function(ebookjson){
// Set the ebook of this page to the book given as json.
var ebook = new Emathbook();
ebook.init(ebookjson);
this.setBook(ebook);
}
EmathbookPage.prototype.saveSettings = function(){
// Save the user settings of this page, such as current page and id of the book.
// var settings = DataTiddler.getData(Emathbook.options.user.datatiddler, 'ebookpages', {});
var settings = Emathbook.options.user.ebookpages;
if (!settings[this.page]){
settings[this.page] = {};
}
settings[this.page].currentpage = this.currentpage; // For compatibility. Remove, when not needed. TODO!
settings[this.page].bookid = this.ebook.bookid;
settings[this.page][this.ebook.bookid] = {'currentpage': this.currentpage, 'lang': Emathbook.options.pages[this.pagenum].lang};
Emathbook.options.saveUserSettingsLocal();
// DataTiddler.setData(Emathbook.options.user.datatiddler, 'ebookpages', settings);
}
EmathbookPage.prototype.getSettings = function(){
// Get the user settings (the current page of current book).
var defaultsettings = {};
// var settings = DataTiddler.getData(Emathbook.options.user.datatiddler, 'ebookpages', defaultsettings);
var settings = Emathbook.options.user.ebookpages || defaultsettings;
if (!settings[this.page]){
settings[this.page] = {};
}
if (!settings[this.page][this.ebook.bookid]){
settings[this.page][this.ebook.bookid] = {};
}
this.currentpage = settings[this.page][this.ebook.bookid].currentpage || this.ebook.frontId();
this.currentlang = settings[this.page][this.ebook.bookid].lang || config.options.txtLang;
}
EmathbookPage.prototype.setPage = function(chapid){
// Change the current page to page with given id.
if (!this.ebook.tocdict[chapid]){
chapid = 'front';
}
for (var i = 0; i < 5 && this.ebook.tocdict[chapid]; i++){
// TODO invent something clever, if page is not found.
if (this.ebook.tocdict[chapid].content != ''){
break;
} else if(this.ebook.tocdict[chapid].chapters.length > 0) {
chapid = this.ebook.tocdict[chapid].chapters[0].chapid;
} else {
return false;
}
}
if (!store.tiddlerExists(this.ebook.tocdict[chapid].content)){
chapid = 'front';
}
if (!store.tiddlerExists(this.ebook.tocdict[chapid].content)){
return false;
}
if (this.page === 'pageOne'){
jQuery('#actionButtons .actionmenu.menuopen .actionmenuitem_Cancel').click();
if (Emathbook.options.user.mqpanelautoshowhide){
if (this.ebook.tocdict[chapid].types.indexOf('assignment') > -1 || this.ebook.tocdict[chapid].types.indexOf('assignments') > -1){
jQuery('body').addClass('showmqpanel');
} else {
jQuery('body').removeClass('showmqpanel');
}
}
}
var pagemap = {'pageOne': 0, 'pageTwo': 1};
var chaptiddler = this.ebook.getContentById(chapid);
var tiddler = store.getTiddler(this.page);
if (!!this.ebook.tocdict[chapid].alttitles){
// TODO! This if/else can be removed, when all tocs have alttitles. Or should it stay in case...
var ebooktitle = this.ebook.tocdict[chapid].alttitles[Emathbook.options.pages[this.pagenum].lang] || this.ebook.tocdict[chapid].title || store.getTiddler(chaptiddler).fields.ebooktitle || '';
} else {
var ebooktitle = this.ebook.tocdict[chapid].title || store.getTiddler(chaptiddler).fields.ebooktitle || '';
}
var headimagetext = this.ebook.getHeadimage(chapid);
var headimagelink = this.ebook.getHeadlink(chapid);
var headstyle = headimagetext ? ' style="background-image: url('+headimagetext+');"' : '';
var headlink = (headimagelink && this.ebook.tocdict[chapid].types.indexOf('chapter') > -1) ? '<a href="'+headimagelink+'" target="blank_" class="headerlink" title="'+headimagelink+'" style="display: block; position: absolute; right: 0; bottom: 0; padding: 1px; border: 1px solid transparent; border-radius: 4px;"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon" style="display: block;"><path style="stroke: none;" d="M17 10 a1.5 1.5 0 1 1 3 3 l-8 8 a1.5 1.5 0 0 1 -3 -3 z M20 6 l-6 6 a4 4 0 0 1 1 -4 l4 -4 a3 3 0 0 1 7 7 l-4 4 a4 4 0 0 1 -4 1 l6 -6 a2.5 2.5 0 1 0 -4 -4 z M5 21 l6 -6 a4 4 0 0 0 -4 1 l-4 4 a3 3 0 0 0 7 7 l4 -4 a4 4 0 0 0 1 -4 l-6 6 a2.5 2.5 0 1 1 -4 -4 z" /></svg></a>' : '';
if (ebooktitle != ''){
ebooktitle = '<html><h1 class="ebooktitle"'+headstyle+'>'+ebooktitle+'</h1></html>\n';
}
var newtext = ebooktitle+'<<tiddler [['+chaptiddler+']]>>\n<<pageinit '+pagemap[this.page]+'>>';
var chaptid = store.getTiddler(chaptiddler);
tiddler.set(tiddler.title, newtext, config.options.txtUserName);
if (this.page == 'pageOne' && Emathbook.config.spreadpages){
var nextpage = store.getTiddler('pageTwo');
if (this.ebook.tocdict[chapid].next){
var nextchap = this.ebook.getContentById(this.ebook.tocdict[chapid].next);
var nexttitle = store.getTiddler(nextchap).fields.ebooktitle || '';
if (nexttitle != ''){
nexttitle = '<html><h1 class="ebooktitle">'+nexttitle+'</h1></html>\n';
}
var nexttext = nexttitle + '<<tiddler [[' + nextchap + ']]>>\n<<pageinit 1>>';
var nextchaptid = store.getTiddler(nextchap);
} else {
var nexttext = '';
}
nextpage.set(nextpage.title, nexttext, config.options.txtUserName);
// EbookPages[1].setPage(this.ebook.tocdict[chapid].next);
refreshElements(jQuery('#pageTwoWrapper')[0], ['pageTwo','pageTwoNavi']);
}
jQuery('#'+this.page).attr('types', this.ebook.tocdict[chapid].types.join(' '));
store.dirty = true;
this.currentpage = chapid;
if (this.timeout){
clearTimeout(this.timeout);
}
var refpage = jQuery('#'+this.page+'Wrapper');
if (refpage.length > 0){
refreshElements(refpage[0],[this.page, this.page+'Navi']);
}
this.setButtonContext();
if (Emathbook.config.showcomments){
var comms = new EbHighlight();
comms.showComments();
}
for (var i = 0; i<EbookPages.length; i++){
if (Emathbook.options.pages[i].refresh){
refreshElements(jQuery('#'+EbookPages[i].page+'Wrapper')[0],[EbookPages[i].page]);
}
}
jQuery('#'+this.page+' h1.ebooktitle').append(headlink);
this.saveSettings();
if (jQuery('#ebcopylistener').length > 0) {
jQuery('#'+this.page+' > span[tiddler]').prepend('<ul class="pagecopytools"><li><a href="javascript:;" class="emslidecrtr-button emslidecrtr-copybutton copythispage"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M2 2 l18 0 l0 6 l-12 0 l0 17 l-6 0 z M10 10 l8 0 l0 10 l10 0 l0 10 l-18 0 z M20 10 l8 8 l-8 0 z" /></svg></a></li></ul>');
jQuery('#'+this.page+' > span[tiddler] > span[tiddler], #'+this.page+' > span[tiddler] > .teacherbox > .ebookbox > div > span[tiddler]').prepend('<ul class="pagecopytools"><li><a href="javascript:;" class="emslidecrtr-button emslidecrtr-copybutton copythiselement"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M2 2 l18 0 l0 6 l-12 0 l0 17 l-6 0 z M10 10 l8 0 l0 10 l10 0 l0 10 l-18 0 z M20 10 l8 8 l-8 0 z" /></svg></a></li></ul>');
jQuery('#'+this.page+' ul.pagecopytools a.emslidecrtr-copybutton').click(function(){
var element = {};
element.type = (jQuery(this).hasClass('copythispage') ? 'page' : 'element');
element.data = jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
jQuery('#ebcopylistener').trigger('ebcopypageelement', [element]);
});
}
}
EmathbookPage.prototype.nextPage = function(){
// Go to next page.
this.setPage(this.ebook.nextPage(this.currentpage));
}
EmathbookPage.prototype.prevPage = function(){
// Go to previous page.
this.setPage(this.ebook.prevPage(this.currentpage));
}
EmathbookPage.prototype.parentPage = function(){
// Go to parent page.
this.setPage(this.ebook.parentPage(this.currentpage));
}
EmathbookPage.prototype.isEmptyPage = function(){
// Check if the current page is empty. (Chapter does not have tiddler given.)
var thispage = this.ebook.getContentById(this.currentpage);
return (thispage == '' || thispage == null);
}
EmathbookPage.prototype.isAssignmentPage = function(){
// Return true, if current page has type "assignment".
return (this.hasType('assignment') || this.hasType('assignments'));
}
EmathbookPage.prototype.isFrontPage = function(){
// Return true, if current page has type "front".
return this.hasType('front');
}
EmathbookPage.prototype.isChapterPage = function(){
// Return true, if current page has type "chapter".
return this.hasType('chapter');
}
EmathbookPage.prototype.isSectionPage = function(){
// Return true, if current page has type "section".
return this.hasType('section');
}
EmathbookPage.prototype.isSubsectionPage = function(){
// Return true, if current page has type "subsection".
return this.hasType('subsection') || this.hasType('topic') || this.hasType('noheader');
}
EmathbookPage.prototype.hasType = function(typename){
// Return true, if current page has given type.
var types = this.ebook.getTypes(this.currentpage);
return (types.indexOf(typename) > -1);
}
EmathbookPage.prototype.getTypes = function(){
// Return an array of types of current page.
return this.ebook.getTypes(this.currentpage);
}
EmathbookPage.prototype.setButtonContext = function(){
// Set the context of the current page on the actionbuttons-panel. Needed to show only available author-menus.
var tidname = jQuery('#pageOne > [tiddler]').attr('tiddler') || EbookPages[0].ebook.tocdict[EbookPages[0].currentpage].content;
var tiddler = store.getTiddler(tidname);
var actionbuttons = jQuery('#actionButtons');
actionbuttons.find('.menuopen').removeClass('menuopen');
actionbuttons.removeClass('context_frontPage context_chapter context_section context_subsection context_assignments');
if (tiddler.tags.indexOf('frontPage') != -1){
actionbuttons.addClass('context_frontPage');
}
if (tiddler.tags.indexOf('chapter') != -1){
actionbuttons.addClass('context_chapter');
}
if (tiddler.tags.indexOf('section') != -1){
actionbuttons.addClass('context_section');
}
if (tiddler.tags.indexOf('subsection') != -1){
actionbuttons.addClass('context_subsection');
}
if (tiddler.tags.indexOf('assignments') != -1){
actionbuttons.addClass('context_assignments');
}
}
EmathbookPage.prototype.getSubToc = function(chapid, lang) {
// Get the sub table of contents as html with the given chapter (or current page) as the root.
if (typeof(chapid) == 'undefined'){
chapid = this.currentpage;
}
return this.ebook.getSubToc(chapid, this.currentpage, null, lang);
}
EmathbookPage.prototype.getElementNumber = function(elemtidname){
// Get the number of the element (examplebox, theorybox,...) in the book.
// If the numbered list is not up to date, generate it.
var elemparts = elemtidname.split('_');
var elemtype = elemparts[elemparts.length - 2];
var elemnum = elemparts[elemparts.length - 1];
var ebook = this.ebook;
if (typeof(Authortool) === 'function' || !this[elemtype+'_'+ebook.bookid]){
this[elemtype+'_'+ebook.bookid] = [];
var chapters = ebook.chapters;
for (var i = 0; i<chapters.length; i++){
var text=store.getTiddlerText(ebook.getContentById(chapters[i]));
if (!!text){
var rex = new RegExp('(?:'+this.ebook.bookid+'_)?'+elemtype+'_[0-9]+', 'g');
var foundelems=text.match(rex);
if (!!foundelems){
for (var j=0; j<foundelems.length; j++){
this[elemtype+'_'+ebook.bookid].push(foundelems[j]);
}
}
}
}
}
return this[elemtype+'_'+ebook.bookid].indexOf(elemtidname) + 1;
}
EmathbookPage.prototype.setElementNumbers = function(parentpage){
// Set numbers of elements (examplebox, theorybox,...) in their places on the page.
// parentpage is an optional argument to decide which page to print element numbers
// default is this page.
var ebookpage = this;
var pagelist = ['pageOne','pageTwo'];
var pagename = (typeof(parentpage) != 'undefined' ? pagelist[parentpage] : this.page);
var refpage = jQuery('#'+pagename+'Wrapper');
var pagenum = pagelist.indexOf(this.page);
refpage.find('.ebookbox').each(function(){
var elemtiddler = jQuery(this).findTiddler();
var elemtype = elemtiddler.split('_');
elemtype = elemtype[elemtype.length -2];
if (['examplebox','theorybox'].indexOf(elemtype) != -1){
jQuery(this).find('h1').eq(0).prepend('<span class="ebookboxnumber">'+EbookDictionary.localize(elemtype, pagenum)+' '+ ebookpage.getElementNumber(elemtiddler)+':</span> ');
}
});
}
//get author modelsolutions
EmathbookPage.prototype.getModelsolutions = function(parentpage){
if(!this.isAssignmentPage){ return false;}
if (typeof(parentpage) === 'undefined'){
parentpage = this.pagenum;
}
var modelsolutions ={};
if(parentpage !== this.pagenum){
if (!this.ebook.tocdict[this.currentpage].next) {
return false;
}
var chaptid = this.ebook.getContentById(this.ebook.tocdict[this.currentpage].next);
}else{
var chaptid = this.getCurrentTiddlerName();
}
var pagelang = EbookPages[parentpage].currentlang;
var tiddler = store.getTiddler(chaptid);
var modelsolutionto = "";
var elements = store.reverseLookup('modelpage',chaptid, true, '+created');
for (var i = 0; i<elements.length; i++){
if (elements[i].fields.elementlanguage && elements[i].fields.elementlanguage !== pagelang ) {
continue;
}
modelsolutionto = elements[i].fields.modelsolutionto;
if (modelsolutions[modelsolutionto] && typeof(modelsolutions[modelsolutionto].length) == 'number'){
modelsolutions[modelsolutionto].push(elements[i].title);
} else {
modelsolutions[modelsolutionto] = [elements[i].title];
}
}
return modelsolutions;
}
//setTeacherelements
EmathbookPage.prototype.setTeacherElements = function(parentpage,modelsolutions){
if (typeof(parentpage) === 'undefined'){
parentpage = this.pagenum;
}
var homeassignments = [];
var teacherBoxes = [];
var otherAssignments = "";
var sdAssignments = "";
//var modelsolutions ={};
if(parentpage !== this.pagenum){
if (!this.ebook.tocdict[this.currentpage].next) {
return false;
}
var chaptid = this.ebook.getContentById(this.ebook.tocdict[this.currentpage].next);
}else{
var chaptid = this.getCurrentTiddlerName();
}
var pagelang = EbookPages[parentpage].currentlang;
var tiddler = store.getTiddler(chaptid);
var elements = store.reverseLookup('teacherchapter',chaptid, true, '+created');
for (var i = 0; i<elements.length; i++){
if (elements[i].fields.elementlanguage && elements[i].fields.elementlanguage !== pagelang ) {
continue;
}
var tdata = elements[i].data('teacherdata');
var anchor = tdata['anchor'] || chaptid;;
var type = tdata['type'];
var elementlanguage = elements[i].fields.elementlanguage || "";
switch(type){
case "assignment":
sdAssignments +=" "+elements[i].title;
break;
case "basic_assignment":
otherAssignments +=" "+elements[i].title;
break;
case "homeassignments":
homeassignments = homeassignments.concat(tdata['homeassignments']);
break;
default:
if (tiddler.isTagged('assignments')){
if( !elementlanguage || pagelang === elementlanguage){
if (modelsolutions[anchor] && typeof(modelsolutions[anchor].length) == 'number'){
modelsolutions[anchor].push(elements[i].title);
} else {
modelsolutions[anchor] = [elements[i].title];
}
}
} else {
teacherBoxes.push(
{"elemAnchor":anchor,
"elemPublished":tdata['published'],
"elemBeforeafter":tdata['beforeafter'],
"elemTitle":elements[i].title}
);
}
break;
}
}
if(teacherBoxes.length>0){
var beginlen = teacherBoxes.length+1;
while(beginlen > teacherBoxes.length){
beginlen=teacherBoxes.length;
for(i=teacherBoxes.length-1;i>-1;i--){
var anchortid = jQuery('.bookpage').eq(parentpage).find('span[tiddler] > span[tiddler="'+teacherBoxes[i]['elemAnchor']+'"],div.teacherbox[tiddler="'+teacherBoxes[i]['elemAnchor']+'"]');
if(anchortid.length >0){
var newbox = jQuery('<div tiddler="'+teacherBoxes[i]['elemTitle']+'" class="teacherbox'+(teacherBoxes[i]['elemPublished'] == 0 ?' notpublishedelement':'')+'">'+(teacherBoxes[i]['elemPublished'] ?' <button class="publishbutton ebook-button" tiddler="'+teacherBoxes[i]['elemTitle']+'">'+Ebooksvgicons['publish']+'<span>'+EbookDictionary.localize('publish')+'</span></button>':'')+'</div>');
var place = teacherBoxes[i]['elemBeforeafter'];
switch (place){
case 'before':
anchortid.before(newbox);
break;
case 'after':
anchortid.after(newbox);
break;
case '':
anchortid = jQuery('.bookpage').eq(parentpage).find('span[tiddler="'+teacherBoxes[i]['elemAnchor']+'"]');
anchortid.append(newbox);
break;
default:
break;
}
wikify('<<tiddler [['+teacherBoxes[i]['elemTitle']+']]>>', newbox[0], null, tiddler);
teacherBoxes.splice(i,1)
}
}
}
if(teacherBoxes.length>0){
for(i=teacherBoxes.length-1;i>-1;i--){
var newbox = jQuery('<div tiddler="'+teacherBoxes[i]['elemTitle']+'" class="teacherbox'+(teacherBoxes[i]['elemPublished'] == 0 ?' notpublishedelement':'')+'">'+(teacherBoxes[i]['elemPublished'] ?' <button class="publishbutton ebook-button" tiddler="'+teacherBoxes[i]['elemTitle']+'">'+Ebooksvgicons['publish']+'<span>'+EbookDictionary.localize('publish')+'</span></button>':'')+'</div>');
jQuery('.bookpage').eq(parentpage).children('span[tiddler]').append(newbox);
wikify('<<tiddler [['+teacherBoxes[i]['elemTitle']+']]>>', newbox[0], null, tiddler);
}
}
}
if(otherAssignments !="" || sdAssignments !=""){
var teacherAccordionWrapper = jQuery('.bookpage').eq(parentpage).find('[tiddler="'+chaptid+'"]').prepend('<h2>'+EbookDictionary.localize('Teachers')+'</h2><div class="teacherAccordions"></div><hr/>').find('.teacherAccordions');
wikify('<<teacherAssignmentAccordion'+sdAssignments+'>>', teacherAccordionWrapper[0], null, tiddler);
}
if(otherAssignments !="" ){
var otherAssignmentlist = otherAssignments.split(' ');
for (var i=0;i<otherAssignmentlist.length;i++){
if(store.tiddlerExists(otherAssignmentlist[i]) && store.getTiddler(otherAssignmentlist[i]).data('teacherdata').published == 0){
jQuery('h3[tiddler="'+otherAssignmentlist[i]+'"]').append('<button class="publishbutton" tiddler="'+otherAssignmentlist[i]+'"><span>'+EbookDictionary.localize('publish')+'</span></button>');
}
}
}
if(otherAssignments !="" || sdAssignments !=""){
var sdAssignmentlist = sdAssignments.split(' ');
for (var i=0;i<sdAssignmentlist.length;i++){
if(store.tiddlerExists(sdAssignmentlist[i]) && store.getTiddler(sdAssignmentlist[i]).data('teacherdata').published == 0){
jQuery('h3[tiddler="'+sdAssignmentlist[i]+'"]').append('<button class="publishbutton" tiddler="'+sdAssignmentlist[i]+'"><span>'+EbookDictionary.localize('publish')+'</span></button>');
}
}
}
var j=0;
for(var anchor in modelsolutions){
var newbox = jQuery('<div class="teacherbox_'+j+'"></div>');
var anchortid = jQuery('.bookpage').eq(parentpage).find('.assignmentAccordion0 h3[tiddler="'+anchor+'"]');
var button = new EbExtrabox('modelsolution', modelsolutions[anchor], newbox);
anchortid.prepend(newbox);
button.showIcon();
j++;
}
for(var j=0; j< homeassignments.length;j++){
try{
jQuery('.bookpage').eq(parentpage).find('h3[tiddler="'+homeassignments[j]['tiddler']+'"]').addClass('homeassignment').attr('homeassignmentType',homeassignments[j]['assignmentType']).append('<span><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-home"><path style="stroke: none;" d="M3 30 l0 -11 l12 -12 l12 12 l0 11 l-9 0 l0 -6 l-6 0 l0 6 z m-1.5 -12 l-1.5 -1.5 l15 -15 l15 15 l-1.5 1.5 l-13.5 -13.5 z m2 -6 l0 -7 l4 0 l0 3z" /></svg></span>');
}catch(e){
testilogit.errorSethomeassignment = chaptid;
}
}
var assignmentHeaders = jQuery('.bookpage').eq(parentpage).find('.assignmentAccordion0 h3');
if (assignmentHeaders.length >0){
for(var i=0;i<assignmentHeaders.length;i++){
var assignmentTitle = assignmentHeaders.eq(i).attr('tiddler');
var solutionsToassignment = [];
var possiblesolutions = store.reverseLookup('solutionto',assignmentTitle,true);
if(typeof(Teachertool) !== 'function'){
for (var j=0;j<possiblesolutions.length;j++){
if (!possiblesolutions[j].data('solution') || possiblesolutions[j].data('solution').creator.toLowerCase() === config.options.txtUserName.toLowerCase()){
solutionsToassignment.push(possiblesolutions[j]);
}
}
}else{
solutionsToassignment = possiblesolutions;
}
var evaluationassignment =jQuery();
var solutionsamount = 0;
for (var j=0;j<solutionsToassignment.length;j++){
if (!(solutionsToassignment[j].data().solution && solutionsToassignment[j].data().solution.editable) || typeof(Teachertool) !== 'function'){
solutionsamount += 1;
evaluationassignment = evaluationassignment.add(store.reverseLookup('markingsto',solutionsToassignment[j].title,true));
}
}
if (solutionsamount >0){
assignmentHeaders.eq(i).find('span.assignmentNroPlace').after('<span class="solutionsAmount"> (<span class="evaluatedSolutions">'+evaluationassignment.length+'</span> / <span class="createdSolutions">'+solutionsamount+'</span>) </span>');
}
}
}
jQuery('.bookpage').eq(parentpage).find('button.publishbutton').click(function(){
var t= new Teachertool();
t.publishTiddler = store.getTiddler(jQuery(this).attr('tiddler'));
t.startAuthoring('publish');
});
}
EmathbookPage.prototype.getLangs = function(){
// Return array of all available languages in current book.
// Default language + altlangs
return this.ebook.getLangs();
}
EmathbookPage.prototype.getNumberedTitle = function(){
// Get numbered title of current page.
return this.ebook.getNumberedTitle(this.currentpage);
}
EmathbookPage.prototype.getCurrentTiddler = function(){
// Get numbered title of current page.
return this.ebook.tocdict[this.currentpage];
}
EmathbookPage.prototype.getCurrentTiddlerName = function(){
// Get numbered title of current page.
return this.ebook.tocdict[this.currentpage].content;
}
//}}}
/***
|''Name:''|Emathbook.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Emathbook-class for E-math ebook|
|''Version:''|1.3|
|''Date:''|November 2, 2012|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131105.1159 ''add'' ''version 1.3''
* this.getPagetype(chapid)
* this.setPagetype(chapid, ptype)
* this.getExtra(chapid)
* this.setExtra(chapid, extra)
* this.isEmptyById(chapid)
* this.hasText(chapid)
<<<
<<<
20131010.1332 ''add'' ''version 1.2''
* Added getTypes(chapid)
<<<
<<<
20130903.1204 ''fix''
* Change settings saving and loading so that they se only one lastCourseSyscheck for all courses.
<<<
<<<
20130917.1520 ''add''
* Added the user settings load for eulexiafontuse -key.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/************************************************************************
* Emathbook -class
* Class for representing the ebook.
************************************************************************/
Emathbook = function(bookid, title, lang, style){
this.bookid = bookid || '';
this.title = title || '';
this.style = style || false;
this.defaultlang = lang || 'en';
this.chapters = [];
this.tocdict = {};
this.frontpage = false;
this.author = [];
this.secondaryauthor = [];
}
Emathbook.config = {
"datatiddler": "SettingsEbook",
"userdatatiddler": "SettingsEbookUser",
"commenttiddler": "EbookComments"
}
Emathbook.options = {
"system": {
"datatiddler": "SettingsEbook",
"firstload": true
},
"user": {
"datatiddler": "SettingsEbookUser",
"commenttiddler": "EbookComments"
},
"pages": [{},{}],
"apps": {},
"courses": {},
"loadUserSettingsLocal": function(){
return JSON.parse((localStorage && localStorage.getItem('ebookusersettings')) || '{}');
},
"loadUserSettings": function(){
var settings = DataTiddler.getDataObject(this.user.datatiddler);
this.user = jQuery.extend(true, this.user, settings);
if ("localStorage" in window && window["localStorage"] != null){
var ebsettings = this.loadUserSettingsLocal();
this.user.ebookpages = jQuery.extend(true, this.user.ebookpages, ebsettings.ebookpages);
this.user.pagetwovisible = ebsettings.pagetwovisible || this.user.pagetwovisible || false;
this.user.ebooktheme = ebsettings.ebooktheme || this.user.ebooktheme || 'default';
this.user.showstepbystep = ebsettings.showstepbystep || false;
this.user.eulexiafontuse = ebsettings.eulexiafontuse || false;
this.user.mqpanelautoshowhide = (typeof(ebsettings.mqpanelautoshowhide) === 'undefined' ? true : ebsettings.mqpanelautoshowhide);
this.user.mqpanelforceshow = ebsettings.mqpanelforceshow || false;
}
},
"saveUserSettingsLocal": function(){
if ("localStorage" in window && window["localStorage"] != null){
localStorage.setItem('ebookusersettings', JSON.stringify(this.user));
} else {
// TODO!
}
},
"saveUserSettings": function(){
this.saveUserSettingsLocal();
var tiddler = store.getTiddler(this.user.datatiddler);
var data = DataTiddler.getDataObject(tiddler);
jQuery.extend(true, data, this.user);
DataTiddler.save(tiddler);
},
"loadCourseSettings": function(){
var tiddlers = store.getTaggedTiddlers('courseSettings');
for (var i = 0; i<tiddlers.length; i++){
var settings = DataTiddler.getDataObject(tiddlers[i].title);
this.courses[settings.courseid] = jQuery.extend({}, settings);
if (this.user.courseChecks){
this.courses.lastCheck = this.user.courseChecks[settings.courseid] || 0;
} else {
this.user.courseChecks = {};
this.user.courseChecks[settings.courseid] = 0;
this.courses[settings.courseid].lastCheck = 0;
}
if (typeof(this.user.courseSysCheck) === 'string'){
this.lastCourseSyscheck = this.user.courseSysCheck || 0;
} else {
this.user.courseSysCheck = 0;
//this.user.courseSysChecks[settings.courseid] = 0;
this.lastCourseSyscheck = 0;
}
var studenttiddler = settings.courseid + '_students';
if (store.tiddlerExists(studenttiddler)){
var stiddler = store.getTiddler(studenttiddler);
var coursedata = stiddler.data('course', {"students": [], "id": settings.courseid.substr(1)});
var studentlist = coursedata.students;
this.courses[settings.courseid].students = {};
for (var i = 0; i < studentlist.length; i++){
this.courses[settings.courseid].students[studentlist[i].userHash] = {
"fname": studentlist[i].fname,
"lname": studentlist[i].lname
}
}
}
}
},
"saveCourseSettings": function(){
for (var courseid in this.courses){
this.user.courseChecks[courseid] = this.courses[courseid].lastCheck;
//this.user.courseSysChecks[courseid] = this.courses[courseid].lastCourseSyscheck;
}
this.user.courseSysCheck = this.lastCourseSyscheck;
this.saveUserSettings();
}
};
Emathbook.prototype.clear = function(){
// Clear the data in ebook.
this.bookid = '';
this.title = '';
this.frontpage = null;
this.style = null;
this.chapters = [];
this.tocdict = {};
}
Emathbook.prototype.init = function(jsontoc){
// Init the ebook from data in json or object format.
if (typeof(jsontoc) == 'string'){
try {
var toc = JSON.parse(jsontoc);
} catch(err) {
var toc = {
"bookid": "0",
"title": "",
"content": "",
"style": "",
"chapters": []
};
}
} else {
var toc = jsontoc;
}
this.bookid = toc.bookid;
this.title = toc.title;
this.alttitles = toc.alttitles;
this.curriculum = toc.curriculum;
this.defaultlang = toc.lang || 'fi';
this.altlangs = toc.altlangs || [];
this.author = toc.author || [];
this.secondaryauthor = toc.secondaryauthor || [];
this.updateURL = toc.updateURL;
this.frontpage = new EmathbookChapter(this);
this.style = toc.style;
this.chapters = [toc.frontpage.chapid];
this.tocdict = {};
this.frontpage.init(toc.frontpage);
this.tocdict[this.frontpage.chapid] = this.frontpage;
this.initNextPrev();
}
Emathbook.prototype.initNextPrev = function(){
// Init the linear next and previous links in chapter nodes.
for (var i = 0; i < this.chapters.length; i++){
if (i > 0){
this.tocdict[this.chapters[i]].prev = this.chapters[i-1];
}
if (i < this.chapters.length - 1){
this.tocdict[this.chapters[i]].next = this.chapters[i+1];
}
}
}
Emathbook.prototype.appendChapter = function(chapid){
// Add new chapter / section / subsection under one with id chapid.
// Add as the last "subchapter".
this.chapters.push(chapid);
}
Emathbook.prototype.addToDict = function(chapter){
// Add given chapter id to the dict.
this.tocdict[chapter.chapid] = chapter;
}
Emathbook.prototype.tocHtml = function(emptyol,beginId,lang){
// Get the toc as html.
var html = '<div class="ebooktoc '+this.style+'">\n';
var title = this.title;
if (lang != this.defaultlang){
title = this.alttitles[lang] || this.title;
}
if (beginId==-1 || beginId==this.frontpage.chapid){html += '<h1>'+title+'</h1>\n';}
if (beginId==-1){
html += this.frontpage.tocHtml(emptyol,true,lang);
}else{
html += this.tocdict[beginId].tocHtml(emptyol,true,lang);
}
html += '</div>\n';
return html;
}
Emathbook.prototype.tocObject = function(){
// Get the toc as json object.
var jsontoc = {
"bookid": this.bookid,
"title": this.title,
"alttitles": this.alttitles || {},
"curriculum": this.curriculum || '',
"lang": this.defaultlang,
"altlangs": this.altlangs || [],
"author": this.author || [],
"secondaryauthor": this.secondaryauthor || [],
"updateURL": this.updateURL || '',
"style": this.style
}
if (this.frontpage){
jsontoc["frontpage"] = this.frontpage.getObject();
} else {
jsontoc["frontpage"] = {};
}
return jsontoc;
}
Emathbook.prototype.tocJson = function(){
// Get the toc as json string
return JSON.stringify(this.tocObject());
}
Emathbook.prototype.writeTocText = function(){
// Export toc to plain text list.
var text = '';
text += '!'+this.bookid+';'+this.title+';'+this.style+'\n';
text += this.frontpage.title +';'+ this.frontpage.chapid +'\n';
var pagetypes = {'1': 'chapter', '2': 'section', '3': 'subsection'};
for (var i = 1; i < this.chapters.length; i++){
var chapter = this.tocdict[this.chapters[i]];
for (var j = 0; j<chapter.chapid.length; j++){
text += '#';
}
text += ' ' + chapter.title + ';' + (chapter.types ? chapter.types.join(' ') : '') + ';' + chapter.chapid + ';' + chapter.content + '\n';
}
return text;
}
Emathbook.prototype.readTocText = function(tiddler){
// Read / import toc from plain text list in given tiddler or from <bookid>_toc_text.
if (!tiddler){
tiddler = this.bookid + '_toc_text';
}
if (!store.tiddlerExists(tiddler)){
return false;
}
var characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var text = store.getTiddlerText(tiddler);
var splitted = text.split('\n');
var booktoc = {};
var bookhead = splitted[0].replace(/^\!*/,'').split(';');
booktoc.bookid = bookhead[0];
booktoc.title = bookhead[1] || '';
booktoc.alttitles = {};
booktoc.curriculum = bookhead[2] || '';
booktoc.lang = bookhead[3] || '';
booktoc.altlangs = bookhead[4].split(' ') || [];
if (booktoc.altlangs.length == 1 && booktoc.altlangs[0] == ''){
booktoc.altlangs = [];
}
booktoc.style = bookhead[5] || '';
booktoc.frontpage = {};
var fronttext = splitted[1].split(';');
booktoc.frontpage.title = fronttext[0] || 'Frontpage';
booktoc.frontpage.chapid = fronttext[1] || 'front';
booktoc.frontpage.types = ["front"];
// booktoc.frontpage.contentLevel = 0;
booktoc.frontpage.content = booktoc.bookid + '_Frontpage';
booktoc.frontpage.chapters = [];
var chapterNum = 0;
var sectionNum = 0;
var subsectionNum = 0;
var chaptext = splitted.join('\n');
var chapters = chaptext.split(/\n#(?!#)/);
for (var i = 1; i<chapters.length && i<characters.length; i++){
var chapter = {};
var ctexts = chapters[i].split('\n')[0].split(';');
chapter.title = (ctexts[0] || '').trim();
chapter.types = ["chapter"].concat((ctexts[1] || '').trim().split(' '));
if (chapter.types[chapter.types.length - 1] === ''){
chapter.types.pop();
}
// chapter.contentLevel = 1;
chapter.chapid = (ctexts[2] || characters[i]).trim();
chapter.content = (ctexts[3] || booktoc.bookid + '_chapter_' + chapterNum).trim();
chapterNum ++;
chapter.chapters = [];
var sections = chapters[i].split(/\n##(?!#)/);
for (var j = 1; j<sections.length && j<characters.length; j++){
var section = {};
var stexts = sections[j].split('\n')[0].split(';');
section.title = (stexts[0] || '').trim();
section.types = ["section"].concat((stexts[1] || '').trim().split());
if (section.types[section.types.length - 1] === ''){
section.types.pop();
}
// section.contentLevel = 2;
section.chapid = (stexts[2] || characters[i] + characters[j]).trim();
section.content = (stexts[3] || booktoc.bookid + '_section_' + sectionNum).trim();
sectionNum++;
section.chapters = [];
var subsections = sections[j].split(/\n###(?!#)/);
for (var k = 1; k<subsections.length && k<characters.length; k++){
var subsection = {};
var sstexts = subsections[k].split('\n')[0].split(';');
subsection.title = (sstexts[0] || '').trim();
subsection.types = (sstexts[1] || '').trim().split();
if (subsection.types[subsection.types.length - 1] === ''){
subsection.types.pop();
}
// subsection.contentLevel = 3;
subsection.chapid = (sstexts[2] || characters[i] + characters[j] + characters[k]).trim();
subsection.content = (sstexts[3] || booktoc.bookid + '_subsection_' + subsectionNum).trim();
subsectionNum++;
subsection.chapters = [];
section.chapters.push(subsection);
}
chapter.chapters.push(section);
}
booktoc.frontpage.chapters.push(chapter);
}
return JSON.stringify(booktoc);
}
Emathbook.prototype.frontId = function(){
// Get the id of frontpage.
return this.frontpage.chapid;
}
Emathbook.prototype.getContentById = function(chapid){
// Get the name of the content tiddler of given chapter.
return this.tocdict[chapid].content;
}
Emathbook.prototype.nextPage = function(currentpage){
// Get the id of the next page of page / chapter with given id.
var newpage = this.tocdict[currentpage].next;
if (!newpage){
newpage = currentpage;
}
return newpage;
}
Emathbook.prototype.prevPage = function(currentpage){
var newpage = this.tocdict[currentpage].prev;
if (!newpage){
newpage = currentpage;
}
return newpage;
}
Emathbook.prototype.parentPage = function(currentpage){
var newpage = this.tocdict[currentpage].parent;
if (typeof(newpage) == 'undefined'){
newpage = currentpage;
}
return newpage;
}
Emathbook.prototype.getTitle = function(chapid, lang){
// Get the title of given chapter
// If optional lang is given, gives the alttitle with that language.
if (!lang || lang == this.defaultlang){
return this.tocdict[chapid].title;
} else if (this.altlangs.indexOf(lang) != -1 && this.tocdict[chapid].alttitles) {
return this.tocdict[chapid].alttitles[lang] || this.tocdict[chapid].title;
} else {
return this.tocdict[chapid].title;
}
}
Emathbook.prototype.getTypes = function(chapid){
// Return an array of types of given chapter.
return this.tocdict[chapid].types.slice(0);
}
Emathbook.prototype.getPath = function(chapid, lang){
var chapter = this.tocdict[chapid];
if (typeof(chapter) != 'undefined'){
if (chapter.parent){
var parent = this.tocdict[chapter.parent];
var patharr = this.getPath(chapter.parent, lang);
var chapindex = parent.indexOfSub(chapid) +1;
} else {
var patharr = []
var chapindex = 0;
}
if (chapter.alttitles){
var title = chapter.alttitles[lang] || chapter.title;
} else {
var title = chapter.title;
}
patharr.push([chapindex, title, chapid]);
return patharr;
} else {
return false;
}
}
Emathbook.prototype.getBreadcrumb = function(chapid, lang){
chapid = chapid || 'front';
if (!this.tocdict[chapid]){
return '';
}
var breadcrumb = [];
var brnumber = [];
var breadcrumbpath = this.getPath(chapid, lang);
breadcrumbpath.shift();
var brnumberafter = (chapid == 'front') ? '' : ':';
for (var i = 0; i<breadcrumbpath.length; i++){
brnumber.push(breadcrumbpath[i][0]);
breadcrumb.push('<span class="breadcrumbchapter" chapid="'+breadcrumbpath[i][2]+'">'+breadcrumbpath[i][1]+'</span>');
}
return '<span class="breadcrumbnumber">'+brnumber.join('.') + brnumberafter + '</span> ' + breadcrumb.join('<span class="breadcrumbdelimiter"> > </span>');
}
Emathbook.prototype.getNumberedTitle = function(chapid, lang){
var patharr = this.getPath(chapid, lang);
var result = '';
if (patharr.length == 1){
result = patharr[0][1];
} else if (patharr.length > 1) {
var numbers = [];
for (var i=1; i<patharr.length; i++){
numbers.push(patharr[i][0]);
}
result = numbers.join('.') + ' ' + patharr[patharr.length -1][1];
}
return result;
}
Emathbook.prototype.getIdByTiddler = function(tiddlerName){
if (typeof(this.tiddlertoc) == 'undefined'){
var chapter = this.frontpage;
this.tiddlertoc = {};
this.tiddlertoc[chapter.content] = chapter.chapid;
while (chapter.next != false){
chapter = this.tocdict[chapter.next];
this.tiddlertoc[chapter.content] = chapter.chapid;
}
}
return this.tiddlertoc[tiddlerName];
}
Emathbook.prototype.getTitleByTiddler = function(tiddlerName, lang){
if (lang && lang != this.defaultlang){
return this.tocdict[this.getIdByTiddler(tiddlerName)].alttitles[lang];
}
return this.tocdict[this.getIdByTiddler(tiddlerName)].title;
}
Emathbook.prototype.getIdByNumber = function(numberstr){
if (typeof(numberstr) != 'string'){
return false;
}
var numbers = numberstr.split('.');
var chapter = this.frontpage;
for (var i = 0; i < numbers.length; i++){
if (parseInt(numbers[i]) != numbers[i]){
return false;
}
try {
chapter = chapter.chapters[parseInt(numbers[i])-1];
} catch (e) {
return false;
}
}
return chapter.chapid;
}
Emathbook.prototype.titleToEbooktitleTiddler = function(tiddlerName){
if (typeof(this.getIdByTiddler(tiddlerName)) == 'undefined'){
return false;
}
var tiddler = store.tiddlerExists(tiddlerName) ? store.getTiddler(tiddlerName) : store.createTiddler(tiddlerName);
tiddler.fields.ebooktitle = this.getTitleByTiddler(tiddlerName);
return true;
}
Emathbook.prototype.getSubToc = function(chapid, currentid, sublevel, lang) {
if (!this.tocdict[chapid]) {
return '';
}
var chapter = this.tocdict[chapid];
var beforehtml = '';
var afterhtml = '';
var itemnumber = this.getNumberedTitle(chapid, lang).match(/^(?:[0-9]+\.)*[0-9]+/) || '';
var itemtext = this.getTitle(chapid, lang);
if (itemtext == ''){
itemtext = this.getTigle(chapid);
}
var conthtml = '';
if (!sublevel){
beforehtml = '<div class="subtocwrapper">\n<div class="subtocinner">\n'+beforehtml;
afterhtml = afterhtml + '</div>\n</div>\n';
conthtml += '<div class="subtocitem" chapid="'+chapid+'"><span class="tocitemnumber">'+ itemnumber + '</span> <a href="javascript:;">' + itemtext + '</a></div>\n';
} else {
var classes = ['subtocitem'];
if (chapid == currentid){
classes.push('iscurrentpage');
}
conthtml = '<li class="'+classes.join(' ')+'" chapid="'+chapid+'"><a href="javascript:;"><span class="tocitemnumber">'+ itemnumber + '</span> ' + itemtext + '</a>\n';
}
if (chapter.chapters.length > 0){
conthtml += '<ul class="subtoc" chapid="'+chapid+'">\n';
for (var i = 0; i < chapter.chapters.length; i++){
conthtml += this.getSubToc(chapter.chapters[i].chapid, currentid, true, lang);
}
conthtml += '</ul>\n';
}
if (!!sublevel){
conthtml += '</li>\n';
}
return beforehtml + conthtml + afterhtml;
}
Emathbook.prototype.getHeadimage = function(chapid){
// Get imagedata for headimage
var parentchapter = this.tocdict[chapid];
while (parentchapter.parent && parentchapter.parent != 'front'){
parentchapter = parentchapter.getParent();
}
var headimage = parentchapter.headimage || '';
if (parentchapter.chapid != this.chapid){
headimage = parentchapter.subheadimage || parentchapter.headimage || '';
}
var headimagetext = store.getTiddlerText(headimage + '##data');
return headimagetext;
}
Emathbook.prototype.getLangs = function(){
// Get an array of all available languages in this book.
return [this.defaultlang].concat(this.altlangs);
}
Emathbook.prototype.getHeadlink = function(chapid){
// Get link for headimage source
var parentchapter = this.tocdict[chapid];
while (parentchapter.parent && parentchapter.parent != 'front'){
parentchapter = parentchapter.getParent();
}
var headimage = parentchapter.headimage || '';
if (parentchapter.chapid != this.chapid){
headimage = parentchapter.subheadimage || parentchapter.headimage || '';
}
var headimagelink = false;
if (headimage) {
headimagelink = store.getTiddlerText(headimage + '##source').match(/https?:\/\/[^\s]*/);
}
return headimagelink;
}
Emathbook.prototype.getPagetype = function(chapid){
// Get the pagetype of given chapter
return this.tocdict[chapid].getPagetype();
}
Emathbook.prototype.setPagetype = function(chapid, ptype){
// Set the pagetype of given chapter
this.tocdict[chapid].setPagetype(ptype);
}
Emathbook.prototype.getExtra = function(chapid){
// Get the extra-information of given chapter
return this.tocdict[chapid].getExtra();
}
Emathbook.prototype.setExtra = function(chapid, extra){
// Set the extra-information of given chapter
this.tocdict[chapid].setExtra(extra);
}
Emathbook.prototype.isEmptyById = function(chapid){
// Returns true if "page" have no content or subcontent
if(!this.tocdict[chapid]) return true;
return !!this.tocdict[chapid] && this.tocdict[chapid].chapters.length ===0 && !this.hasText(chapid);
}
Emathbook.prototype.hasText = function(chapid){
// Returns true if "page" have content
var text= store.getTiddlerText(this.getContentById(chapid),'');
if(text !=="" && text.indexOf('ebook_assignmentlist_') === -1){
return true;
}
if(text.indexOf('ebook_assignmentlist_') !== -1
&& store.getTiddlerText(this.bookid+"_ebook_assignmentlist_"+text.match(/ebook_assignmentlist_[0-9]*/)[0].split("_")[2],'').indexOf('assignment_') !== -1){
return true;
}
return false;
}
//}}}
/***
|''Name:''|Emathbook.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|EmathbookChapter-class for E-math ebook|
|''Version:''|1.0|
|''Date:''|November 2, 2012|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131105.1145 ''add'' ''version 1.0''
* this.pagetype
* this.getPagetype()
* this.setPagetype(ptype)
* this.getExtra()
* this.setExtra(extra)
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/***************************************************
* EmathbookChapter -class
***************************************************/
EmathbookChapter = function(ebook, chapid, title, content, types){
this.ebook = ebook;
this.chapid = chapid || '';
this.title = title || '';
this.alttitles = {};
this.content = content || '';
this.types = types || [];
this.headimage = '';
this.subheadimage = '';
this.chapters = [];
this.parent = false;
this.next = false;
this.prev = false;
}
EmathbookChapter.prototype.init = function(chapdata, parent){
if (typeof(parent) == 'undefined'){
parent = false;
}
this.chapid = chapdata.chapid;
this.title = chapdata.title;
this.alttitles = chapdata.alttitles;
this.content = chapdata.content;
this.types = chapdata.types || [];
this.pagetype = chapdata.pagetype || '';
this.extra = chapdata.extra || '';
this.headimage = chapdata.headimage || '';
this.subheadimage = chapdata.subheadimage || '';
this.parent = parent;
for (var i = 0; i < chapdata.chapters.length; i++){
var newchap = new EmathbookChapter(this.ebook);
if (chapdata.chapters[i].content != ''){
this.ebook.appendChapter(chapdata.chapters[i].chapid);
}
newchap.init(chapdata.chapters[i], this.chapid);
this.ebook.addToDict(newchap);
this.chapters.push(newchap);
}
}
EmathbookChapter.prototype.getParent = function(){
return this.ebook.tocdict[this.parent];
}
EmathbookChapter.prototype.addSubchapter = function(chapter){
this.chapters.push(chapter);
}
EmathbookChapter.prototype.removeSubchapter = function(chapid){
var i = this.indexOfSub(chapid);
this.chapters.splice(i,1);
}
EmathbookChapter.prototype.indexOfSub = function(chapid){
var i = 0;
while (i < this.chapters.length && this.chapters[i].chapid != chapid){
i++;
}
if (this.chapters[i] && this.chapters[i].chapid == chapid){
return i;
} else {
return -1;
}
}
EmathbookChapter.prototype.tocHtml = function(emptyol, nolist, lang){
var title = this.alttitles[lang] || this.title;
if (this.parent == false || nolist){
var html = '<h2><a href="javascript:" chapid="'+this.chapid+'">'+ title + '</a></h2>\n';
var endhtml = '';
} else {
var html = '<li id="tocid_'+this.chapid+'" class="ebooktocitem">\n';
html += '<a href="javascript:" chapid="'+this.chapid+'">'+ title + '</a>\n';
var endhtml = '</li>\n';
}
if (this.chapters.length > 0){
html += '<ol class="ebooktocsubchap">\n';
for (var i=0; i < this.chapters.length; i++){
html += this.chapters[i].tocHtml(emptyol, null, lang);
}
html += '</ol>\n';
} else if (emptyol){
html += '<ol class="ebooktocsubchap"></ol>\n';
}
html += endhtml;
return html;
}
EmathbookChapter.prototype.getObject = function(){
var json = {
"title": this.title,
"alttitles": this.alttitles,
"types": this.types,
"pagetype": this.pagetype,
"chapid": this.chapid,
"content": this.content,
"chapters": []
}
if (this.headimage){
json.headimage = this.headimage;
}
if (this.subheadimage){
json.subheadimage = this.subheadimage;
}
for (var i = 0; i < this.chapters.length; i++){
json.chapters.push(this.chapters[i].getObject());
}
return json;
}
EmathbookChapter.prototype.getPagetype = function(){
return this.pagetype;
}
EmathbookChapter.prototype.setPagetype = function(ptype){
this.pagetype = ptype;
}
EmathbookChapter.prototype.getExtra = function(){
return this.extra;
}
EmathbookChapter.prototype.setExtra = function(extra){
this.extra = extra;
}
//}}}
/***
|Emathbook.js(5)|
|Version|1.0|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|License|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|Description|Emathbook ping for E-math ebook|
!!!!!Revisions
<<<
20131006.1315 ''Version 1.0''
* Moved sendComment
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/*******************************************************
* Emathbook update functions
*******************************************************/
Emathbook.pingServer = function(updateurl){
jQuery('li#onlineindicator').removeClass('serveronline').removeClass('serveroffline');
if(typeof(updateurl)=="undefined"){
if (typeof(Authortool)=="function"){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
updateurl = configs.updateURL.split('/');
}else{
updateurl = Emathbook.options.courses[Emathbook.options.pages[0].courseid].updateURL.split('/');
}
updateurl.pop();
updateurl = updateurl.join('/')+"/ping.php";
}
var response = jQuery.postCORS(updateurl, function(repdata){
if (response.status == 200){
if (repdata == 'ok'){
jQuery('li#onlineindicator').addClass('serveronline');
} else {
jQuery('li#onlineindicator').addClass('serveroffline');
}
}else{
jQuery('li#onlineindicator').addClass('serveroffline');
}
});
//Debug: ping response
//testilogit.serverping = response;
}
//}}}
/***
|''Name:''|Emathbook.js(6)|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Emathbook helper functions for E-math ebook. (Prompt, step-by-step, load-save,...|
|''Version:''|1.1|
|''Date:''|November 2, 2012|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131220.1510 ''add''
* offline promptUser functionality
<<<
<<<
20131006.1332 ''add''
* Colorinfo to errors
<<<
<<<
20130923.1132 ''add''
* Added bookcheck to usercheck in promtuser function.
* Added special error types and messages to wrong course logins.
<<<
<<<
20130903.1202 ''add''
* Added closePageTwo function.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/*******************************************************
* Emathbook username functions
*******************************************************/
Emathbook.showUserName = function(){
if (config.options.txtUserName == '' || config.options.txtUserName == 'YourName' || (!config.options.txtUserKey && Emathbook.options.pages[0].courseid !=="offline")){
Emathbook.promptUserName();
}
return '<div class="showusername"><span class="usernametext">'+EbookDictionary.localize('username')+': <a href="javascript:;">'+config.options.txtUserName+'</a></span></div>';
}
Emathbook.promptUserName = function(){
var username = config.options.txtUserName;
if(Emathbook.options.pages[0].courseid ==="offline"){
jQuery('body').addClass('offlineuse');
}
if (jQuery('#tiddlyemath-message-box').length === 0 && navigator.userAgent.indexOf('Firefox') > -1){
if (jQuery('#tiddlyemath-install-dialog').length === 0){
store.dirty = false;
var plugindialog = jQuery('body').append('<div id="tiddlyemath-install-dialog"><h3>'+EbookDictionary.localize('please install plugin')+'</h3><a href="data/tiddlyemath.xpi">'+EbookDictionary.localize('click here')+'</a></div>').find('#tiddlyemath-install-dialog');
plugindialog.dialog({
title: 'E-Math-plugin',
modal: true,
closeOnEscape: false
});
};
return false;
}
if (typeof(Authortool) === 'function'){
var checkurl = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""}).updateURL;
var askCourseId = false;
}else{
var checkurl = Emathbook.options.pages[0].courseid && Emathbook.options.courses[Emathbook.options.pages[0].courseid] && Emathbook.options.courses[Emathbook.options.pages[0].courseid].updateURL || "";
var askCourseId = true;
}
var nameprompt = jQuery('<div id="askusername"><h1>'+EbookDictionary.localize('give userdata')+'</h1>'+(!checkurl ?'<p class="hideoffline onelinenowrap">'+EbookDictionary.localize('updateURL')+': <input type="url" name="getcheckurl" id="getcheckurl" value="" /></p>':'')+'<p class="onelinenowrap">'+EbookDictionary.localize('username')+': <input type="text" name="getusername" id="getusername" value="" /></p><p class="onelinenowrap hideoffline">'+EbookDictionary.localize('userkey')+': <input type="password" name="getuserkey" id="getuserkey" value="" /></p><p class="onelinenowrap hideoffline">'+EbookDictionary.localize('show userkey')+': <input type="checkbox" name="showuserkey" id="showuserkey" /></p>'+(askCourseId ?'<p class="onelinenowrap hideoffline">'+EbookDictionary.localize('courseid')+': <input type="text" name="getcourseid" id="getcourseid" value="" /></p>':'')+'</div>');
jQuery('#askusername').remove();
jQuery('body').append(nameprompt);
nameprompt.find('#showuserkey').change(function(){
var $input = jQuery(this).parents('#askusername').find('#getuserkey');
if (jQuery(this).is(':checked')){
jQuery('<input type="text" name="getuserkey" id="getuserkey" value="'+$input.val()+'" />').insertBefore($input);
} else {
jQuery('<input type="password" name="getuserkey" id="getuserkey" value="'+$input.val()+'" />').insertBefore($input);
}
$input.remove();
});
nameprompt.dialog({
title: 'User information',
modal: true,
width: '630px',
buttons: [
{
text:EbookDictionary.localize('connect book to coursemanagement'),
id:"coursemanagementswitch",
click: function(){
jQuery('body').toggleClass('offlineuse');
if(jQuery('body').hasClass('offlineuse')){
if(config.options.txtUserName){
jQuery(this).dialog('destroy').remove();
}else{
jQuery('#coursemanagementswitch .ui-button-text').text(EbookDictionary.localize('connect book to coursemanagement'));
}
}else{
jQuery('#coursemanagementswitch .ui-button-text').text(EbookDictionary.localize('cancel'));
}
}
},
{
text:"OK",
click: function(){
jQuery('#getusername,#getuserkey,#getcourseid').css('background-color','white');
if(jQuery('body').hasClass('offlineuse')){
var username = jQuery('#askusername input#getusername').val().replace(/\"/g,"");
if (username == '' || username == 'YourName'){
alert(EbookDictionary.localize('give all information'));
} else {
config.options.txtUserName = username;
saveOptionCookie('txtUserName');
var conftiddler = store.getTiddler('ConfigTweaks');
var newtext = conftiddler.text.replace(/config\.options\.txtUserName[\ ]*=[\ ]*\"[^\"]*\"\;/, 'config.options.txtUserName="'+username+'";');
conftiddler.set(conftiddler.title, newtext, username);
store.dirty = true;
saveChanges();
jQuery(this).dialog('destroy').remove();
}
}else{
var username = jQuery('#askusername input#getusername').val();
var userkey = jQuery('#askusername input#getuserkey').val();
var ajaxURL = checkurl || jQuery('#askusername input#getcheckurl').val();
if(askCourseId){
var courseid = jQuery('#askusername input#getcourseid').val();
}else{
var courseid = [navigator.userAgent];
for (var i = 0; i < navigator.plugins.length; i++){
courseid.push(navigator.plugins[i].name);
}
courseid = JSON.stringify(courseid);
}
if (username == '' || username == 'YourName' || userkey == ''){
alert(EbookDictionary.localize('give all information'));
} else {
var callback = function(data){
if (response.status == 200){
if (data == 'OK'){
if(askCourseId){
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var currents = store.getTaggedTiddlers('currentCourse');
for (var i = 0; i < currents.length; i++){
currents[i].tags.remove('currentCourse');
currents[i].set();
}
var coursetiddler = store.createTiddler('course_'+courseid);
var coursetiddlerData = jQuery.extend({},DataTiddler.getDataObject('course_template'));
if(!checkurl){
coursetiddlerData.updateURL = ajaxURL;
} else{
coursetiddlerData.updateURL = checkurl;
}
coursetiddler.set('course_'+courseid, '<data>'+JSON.stringify(coursetiddlerData)+'</data>', username, new Date(), ['courseSettings','currentCourse']);
DataTiddler.setData('course_'+courseid, 'courseid', courseid);
}
var conftiddler = store.getTiddler('ConfigTweaks');
var newtext = conftiddler.text.replace(/config\.options\.txtUserName=\"[^\"]*\"\;/, 'config.options.txtUserName="'+username+'";');
if ((/config\.options\.txtUserKey=\"[^\"]*\"\;/).test(newtext)){
newtext = newtext.replace(/config\.options\.txtUserKey=\"[^\"]*\"\;/, 'config.options.txtUserKey="'+userkey+'";');
} else {
newtext = newtext.replace('//}}}','config.options.txtUserKey="'+userkey+'";\n//}}}');
}
if(!checkurl){
if (typeof(Authortool) === 'function'){
var oldConfig = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
oldConfig.updateURL = ajaxURL;
DataTiddler.setData(Emathbook.config.datatiddler, 'config', oldConfig);
}
}else{
if (typeof(Authortool) === 'function'){
var oldConfig = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
oldConfig.updateURL = checkurl;
DataTiddler.setData(Emathbook.config.datatiddler, 'config', oldConfig);
}
}
config.options.txtUserKey = userkey;
conftiddler.set(conftiddler.title, newtext, username);
store.dirty = true;
var disableTidllers = store.getTaggedTiddlers('disablesendstiddler');
for(var i=0;i<disableTidllers.length;i++){
disableTidllers[i].set(disableTidllers[i].title,disableTidllers[i].text,null,null,['disablesendstiddler']);
}
config.options.chkAutoSave = autosaveStatus;
saveChanges();
saveOptionCookie('txtUserName');
setTimeout("window.location.reload()", 1000);
} else {
var errortype=-1;
var errormsg = "";
try{
var errorObject = JSON.parse(data);
errortype=parseInt(errorObject.errortype);
errormsg=errorObject.errormessage || "";
}catch(e){
}
switch(errortype){
case 0:
jQuery('#getusername,#getuserkey').css('background-color','#FFAAAA');
alert(EbookDictionary.localize('invalid user'));
break;
case 1:
jQuery('#getcourseid').css('background-color','#FFAAAA');
alert(EbookDictionary.localize('invalid course'));
break;
case 2:
jQuery('#getcourseid').css('background-color','#FFAAAA');
alert(EbookDictionary.localize('invalid courseBook')+"\n"+EbookDictionary.localize('correct coursebook')+':'+errormsg);
break;
default:
jQuery('#getusername,#getuserkey').css('background-color','#FFAAAA');
alert(EbookDictionary.localize('invalid user'));
break;
}
}
} else {
alert(EbookDictionary.localize('connection error'));
}
}
var response = jQuery.postCORS(ajaxURL, {"type": "12", "username": username, "userkey": userkey, "courseid": courseid, "bookids":bookshelf.getAvailableBooksIds().join(',')}, callback);
}
}
}
}
],
close: function(event, ui){
setTimeout('refreshAll();', 520);
}
});
if(jQuery('body').hasClass('courseconnect')){
jQuery('body').removeClass('courseconnect');
jQuery('#coursemanagementswitch').click();
}
if(typeof(Authortool) === "function" || Emathbook.options.pages[0].courseid !=="offline"){
jQuery('#coursemanagementswitch').remove();
}
}
/*******************************************************
* Emathbook binary load/save functions
*******************************************************/
Emathbook.loadFileBinary = function(fileUrl){
var r = Emathbook.mozillaLoadFileBinary(fileUrl);
if (r == null || r == false) {
r = Emathbook.ieLoadFileBinary(fileUrl);
}
if (r == null || r == false) {
r = Emathbook.javaLoadFileBinary(fileUrl);
}
return r;
}
Emathbook.javaLoadFileBinary = function(filePath){
return false;
}
Emathbook.ieLoadFileBinary = function(filePath){
return false;
}
Emathbook.mozillaLoadFileBinary = function(filePath) {
if (!window.Components) {
return null;
}
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (e) {
alert("access denied: " + filePath);
return null;
}
var file = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
try {
file.initWithPath(filePath);
} catch (e) {
alert("cannot read file - invalid path: " + filePath);
return null;
}
if (!file.exists()) {
alert("cannot read file - not found: " + filePath);
return null;
}
var inputStream = Components.classes['@mozilla.org/network/file-input-stream;1'].createInstance(Components.interfaces.nsIFileInputStream);
inputStream.init(file, 1, 4, null);
var bInputStream = Components.classes['@mozilla.org/binaryinputstream;1'].createInstance(Components.interfaces.nsIBinaryInputStream);
bInputStream.setInputStream(inputStream);
return bInputStream.readBytes(inputStream.available());
}
Emathbook.saveFileBinary = function(fileUrl, content) {
var r = Emathbook.mozillaSaveFileBinary(fileUrl, content);
if (!r) {
r = Emathbook.ieSaveFileBinary(fileUrl, content);
}
if (!r) {
r = Emathbook.javaSaveFileBinary(fileUrl, content);
}
return r;
}
Emathbook.javaSaveFileBinary = function(filePath){
return false;
}
Emathbook.ieSaveFileBinary = function(filePath){
return false;
}
Emathbook.mozillaSaveFileBinary = function(filePath, content) {
if (window.Components) {
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
} catch (e){
alert("access denied: " + filePath);
return false;
}
var file = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
try {
file.initWithPath(filePath);
} catch (e) {
alert("can not open file - invalid path: " + filePath);
return false;
}
if (!file.exists()) {
file.create(0, 436);
}
var outStream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
outStream.init(file, 0x04 | 0x08 | 0x20, 0600, null); // readwrite, create, truncate
outStream.write(content, content.length);
if (outStream instanceof Components.interfaces.nsISafeOutputStream){
outStream.finish();
} else {
outStream.flush();
outStream.close();
}
return true;
}
return false;
}
Emathbook.decodeBase64 = function(input) {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var out = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = enc1 << 2 | enc2 >> 4;
chr2 = (enc2 & 15) << 4 | enc3 >> 2;
chr3 = (enc3 & 3) << 6 | enc4;
out = out + String.fromCharCode(chr1);
if (enc3 != 64) {
out = out + String.fromCharCode(chr2);
}
if (enc4 != 64) {
out = out + String.fromCharCode(chr3);
}
} while (i < input.length);
return out;
}
Emathbook.saveExternals = function(){
var tiddlers = store.getTaggedTiddlers('external_file');
var filepath = window.location.href.replace(/^file:\/\/\//,'');
var fileparts = filepath.split('/');
fileparts.pop();
filepath = fileparts.join('/') + '/';
filepath = decodeURIComponent(filepath);
filepath = (filepath[1] != ':' ? '/'+filepath : filepath.replace(/\//g,'\\'));
for (var i = tiddlers.length-1; i > -1; i--){
var filename = store.getTiddlerText(tiddlers[i].title + '##file');
if (filepath[1] == ':'){
filename = filename.replace(/\//g,'\\');
}
var fileurl = filepath + filename;
var filedata = store.getTiddlerText(tiddlers[i].title + '##data').replace(/^data:.*;base64,/,'');
try {
var successed = Emathbook.saveFileBinary(fileurl, Emathbook.decodeBase64(filedata));
} catch (e) {
alert('Something went wrong. Contact Petri!\nError code: 8a589: ' + tiddlers[i].title);
}
if (successed){
tiddlers[i].tags.remove('external_file');
}
if (successed && tiddlers[i].isTagged('remove_tiddler')){
store.removeTiddler(tiddlers[i].title);
}
}
return true;
}
/***************************************************
* Emathbook create solution
***************************************************/
Emathbook.createSolution = function(assignmentTitle,tiddlerText){
var solutionTiddlerName =Emathbook.options.pages[0].courseid+"_"+config.options.txtUserName+"_offline_solution_";
var i=0;
while(store.tiddlerExists(solutionTiddlerName+i)){i++;}
solutionTiddlerName += i;
var solutionTiddler = store.createTiddler(solutionTiddlerName);
solutionTiddler.set(solutionTiddlerName,(typeof(tiddlerText)=="undefined" ? '<<ebooksolution>>':(typeof(tiddlerText)=="string" ? tiddlerText : tiddlerText.text)),null,null,['solutiondata','offlinesolution'],null,{"solutionto":assignmentTitle},config.options.txtUserName);
return solutionTiddlerName;
}
/***************************************************
* Emathbook SD show step by step
***************************************************/
Emathbook.showStepByStep = function(element){
if(typeof(element)=="object"){
var sdtables = element.find('div.structuredderivation > table.sdtable');
}else{
var pagenroToId={0:"One",1:"Two"};
var sdtables = jQuery('#page'+pagenroToId[element]+' div.ebookbox div.structuredderivation > table.sdtable').not('.sdbookassignmentlist table.sdtable');
}
var sdtablerowlist = [];
var showindexlist = [];
for(var i=0;i<sdtables.length;i++){
sdtablerowlist[i] = sdtables.eq(i).find('tr:not(.sdhidden tr, .sdhidden)');
sdtablerowlist[i].find('td.ldots > span').bind('click.blockopen', function(e){return false;});
if( sdtablerowlist[i].length === 2){continue;}
var stepBystepButtons = '<tr class="stepBystepButtons"><td></td><td><div class="stepBystepButtonset" tablenumber="'+i+'"><button stepscount ="'+sdtablerowlist[i].length+'" class="prevstepButton">PREV</button><button class="allstepsButton">ALL</button><button stepscount ="'+sdtablerowlist[i].length+'" class="nextstepButton">NEXT</button></div></td></tr>';
sdtablerowlist[i].hide();
sdtablerowlist[i].eq(0).show();
showindexlist[i] = 1;
sdtables.eq(i).delegate("button.nextstepButton" , "click", function(){
var button = jQuery(this);
var tableindex = button.parent().attr('tablenumber');
var sdtablerows = sdtablerowlist[tableindex];
sdtablerows.eq(showindexlist[tableindex]).show();
showindexlist[tableindex]++;
if (sdtablerows.eq(showindexlist[tableindex]).find('td').eq(1).hasClass('subderivation')){
sdtablerows.eq(showindexlist[tableindex]).show();
showindexlist[tableindex]++;
}
if (showindexlist[tableindex] === sdtablerows.length -1){
sdtablerows.eq(showindexlist[tableindex]).show();
button.parents('tr.stepBystepButtons').remove();
sdtablerows.find('td.ldots > span').unbind('click.blockopen');
}
});
sdtables.eq(i).delegate("button.prevstepButton" , "click", function(){
var button = jQuery(this);
var tableindex = button.parent().attr('tablenumber');
var sdtablerows = sdtablerowlist[tableindex];
if (showindexlist[tableindex] === 1){
return true;
}
showindexlist[tableindex]--;
sdtablerows.eq(showindexlist[tableindex]).hide();
if (sdtablerows.eq(showindexlist[tableindex]).find('td').eq(1).hasClass('subderivation')){
showindexlist[tableindex]--;
sdtablerows.eq(showindexlist[tableindex]).hide();
}
});
sdtables.eq(i).delegate("button.allstepsButton" , "click" ,function(){
jQuery(this).parents('table.sdtable').eq(0).find('tr').show();
jQuery(this).parents('tr.stepBystepButtons').remove();
jQuery(this).parents('table.sdtable').find('td.ldots > span').unbind('click.blockopen');
});
sdtables.eq(i).append(stepBystepButtons)
.find('button.prevstepButton').button({
icons: {primary: "ui-icon-circle-arrow-w"},
text: false
}).next().button({
icons: {primary: "ui-icon-circle-arrow-s"},
text: false
}).next().button({
icons: {primary: "ui-icon-circle-arrow-e"},
text: false
}).parent().buttonset();
}
}
/***************************************************
* Emathbook print preview
***************************************************/
Emathbook.print = function(ref, type){
var hiddendivs = jQuery('body > div:visible').not('#JashParent').addClass('printhide');
jQuery('body').addClass('emathprintpreview');
jQuery('body').append('<div id="emathprint" style="background-color: white;"><div class="printtools"><a href="javascript:;" id="print">'+EbookDictionary.localize('print')+'</a> <a href="javascript:;" id="printmarkings">'+EbookDictionary.localize('markings')+'</a> <a href="javascript:;" id="printclose">'+EbookDictionary.localize('close')+'</a></div></div>');
var printdiv = jQuery('#emathprint');
printdiv.find('.printtools a#print').button({
icons: {primary: 'emui-icon-print'},
text: false
});
printdiv.find('.printtools a#printmarkings').button({
icons: {primary: 'emui-icon-comment-show'},
text: false
});
printdiv.find('.printtools a#printclose').button({
icons: {primary: 'ui-icon-closethick'},
text: false
});
switch (type){
case 'solution':
var $assignment = jQuery(ref).parents('.ui-accordion-content');
var pagenum = ({'pageOne': 0, 'pageTwo': 1})[$assignment.parents('.bookpage').attr('id')];
var booktitle = EbookPages[0].ebook.alttitles[EbookPages[pagenum].currentlang] || EbookPages[pagenum].ebook.title;
var assnumber = $assignment.prev().find('.assignmentNroPlace').text();
var questiontiddler = $assignment.find('.assignment_text').attr('tiddler');
var solutiontiddler = $assignment.find('.solutioncontent > span[tiddler]').attr('tiddler');
var printtempsol = store.createTiddler('printtempsolution');
printtempsol.set(printtempsol.title, store.getTiddlerText(solutiontiddler));
var soldata = printtempsol.data('solution');
soldata.editable = false;
printtempsol.setData('solution', soldata);
wikify('!!'+booktitle+'\n!'+EbookDictionary.localize('assignmentTexture')+' '+assnumber+'\n{{printassignment{\n<<tiddler [['+questiontiddler+']]>>}}}\n{{printsolution{\<<tiddler [[printtempsolution]]>>}}}', printdiv[0]);
var markingtiddler = store.reverseLookup("markingsto", solutiontiddler, true);
if (markingtiddler.length > 0) {
markingtiddler = markingtiddler[0].title;
var markings = new SdMarkings({tiddler: markingtiddler});
markings.read();
markings.show(printdiv[0]);
}
break;
default:
break;
}
printdiv.find('.removesolelem, button, a.button').remove();
jQuery('body').find('a#print').click(function(e){
window.print();
});
jQuery('body').find('a#printmarkings').click(function(e){
var $emprint = jQuery('#emathprint');
$emprint.toggleClass('printmarkingsshow');
var $icon = jQuery(this).find('.emui-icon-comment-show, .emui-icon-comment-hide');
$icon.toggleClass('emui-icon-comment-show');
$icon.toggleClass('emui-icon-comment-hide');
});
jQuery('body').find('a#printclose').click(function(e){
hiddendivs.removeClass('printhide');
jQuery('body').removeClass('emathprintpreview');
printdiv.remove();
});
}
/***************************************************
* Emathbook open app-window
***************************************************/
Emathbook.appopen = function(appname){
var apps = {
'calculator': {
'title': 'Calculator',
'jqname': 'calculator',
'options': null,
'dialogops': {}
},
'funcgraph': {
'title': 'Graphs',
'jqname': 'emathfuncgraph',
'options': {editable: true},
'dialogops': {width: 750}
}
}
var app = apps[appname];
var dialogsettings = jQuery.extend({
title: app.title,
resizable: false,
closeOnEscape: false,
close: function(event,ui){
jQuery(this).dialog('destroy').remove();
},
open: function(event, ui){
jQuery(this).parent().find('a.ui-dialog-titlebar-close').show()
.before('<a class="ui-dialog-titlebar-minmax ui-corner-all" href="#" role="button" style="display:inline; position: absolute; right: 3em;"><span class="ui-icon ui-icon-arrowthickstop-1-n"></span></a>')
.end().find('a.ui-dialog-titlebar-minmax').click(function(){
if (jQuery(this).find('span').hasClass('ui-icon-arrowthickstop-1-n')){
jQuery(this).find('span').removeClass('ui-icon-arrowthickstop-1-n').addClass('ui-icon-arrowthickstop-1-s');
jQuery(this).parents('.ui-dialog').find('.'+app.jqname).slideUp('fast');
} else {
jQuery(this).find('span').removeClass('ui-icon-arrowthickstop-1-s').addClass('ui-icon-arrowthickstop-1-n');
jQuery(this).parents('.ui-dialog').find('.'+app.jqname).slideDown('fast');
}
});
}
}, app.dialogops);
jQuery('<div class="floatapp-'+app.jqname+'"></div>')
.dialog(dialogsettings)[app.jqname](app.options);
}
/***************************************************
* Emathbook modalProgressDialog
***************************************************/
Emathbook.modalProgressDialog = function(dialogId,dialogTilte,dialogMessage,doFunction,timeouted){
var thisDialog = jQuery('body').append('<div id="'+dialogId+'" title="'+EbookDictionary.localize(dialogTilte)+'..."><p class="currentState">'+EbookDictionary.localize(dialogMessage)+'</p></div>').find('#'+dialogId);
thisDialog.dialog({
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false
});
thisDialog.parent().find('.ui-dialog-titlebar-close').remove();
if(typeof(timeouted)==="undefined"){
doFunction();
}else{
setTimeout(doFunction,timeouted);
}
}
/***************************************************
* Emathbook saveEbook
***************************************************/
Emathbook.saveEbook = function(manual){
var savingType=(typeof(manual)==="undefined"?'automaticsave':'manualsave');
var savingInfo = jQuery('body').addClass('savingBook').append('<div id="savingBook" class="'+savingType+'">'+EbookDictionary.localize(savingType)+'</div>').find('#savingBook');
saveChanges();
jQuery('body').removeClass('savingBook');
savingInfo.remove();
}
/***************************************************
* Emathbook closePageTwo
***************************************************/
Emathbook.closePageTwo = function(){
jQuery('#contentWrapper').addClass('pageclosed').removeAttr('pageopen');
Emathbook.options.user.pagetwovisible = false;
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
Emathbook.options.saveUserSettings();
config.options.chkAutoSave = autosaveStatus;
}
//}}}
/***
|''Name:''|Emathbook(7).js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Emathbook update functions for E-math ebook|
|''Version:''|0.3|
|''Date:''|November 2, 2012|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131006.1436 ''fix''
* Moved functions to right places
* Old updatefunction has removed
<<<
<<<
20130821.1120 ''fix''
* Emathbook.systemUpdate - SystemUpdate dont refresh unless is needed (only js updates)
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
Emathbook.getContentUpdates = function(){
var bookids = bookshelf.getAvailableBooksIds();
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {});
upddata.lastChecks = upddata.lastChecks || {};
var updateurl = configs.updateURL;
var lastCheck =[];
for (var i=0; i < bookids.length;i++){
lastCheck.push(Emathbook.options.user.updates.lastChecks[bookids[i]] || upddata.lastChecks[bookids[i]] || '0');
}
callback = function(data){
//testilogit.contentUp = response;
var loadscreen = jQuery('body #loadBookscreen');
if (response.status == 200){
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').show();
var serverTime = data.substring(0,data.indexOf('_'));
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
var updateInfo = updelem.find('[updateinfo]');
store.importTiddlyWiki(data);
for (var i=0; i < bookids.length;i++){
Emathbook.options.user.updates.lastChecks[bookids[i]] = serverTime;
}
Emathbook.options.saveUserSettings();
var tocchanged=false;
if(data.match(/tags="[^"]*ebooktoc[^"]*"/)){
//Move to own function????
tocchanged = true;
bookshelf.init();
EbookPages[0].setBook(bookshelf.getBook(EbookPages[0].ebook.bookid));
EbookPages[1].setBook(bookshelf.getBook(EbookPages[1].ebook.bookid));
}
autoSaveChanges();
if(loadscreen.length == 0){
alert(numberOfUpdates+" updates done!");
refreshElements(jQuery('#pageOneWrapper')[0]);
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('contentupdates done'));
if(tocchanged){
var updatedTocs = data.match(/title="[^_"]*_toc"/g);
var updatedTocsTitles = [];
for(var i=0;i< (updatedTocs?updatedTocs.length:updatedTocs);i++){
try{
updatedTocsTitles.push(bookshelf.getBookTitle(updatedTocs[i].replace('title="','').replace('_toc"','')));
}catch(e){
//testilogit.tocupdateError = e;
}
}
loadscreen.find('p.currentState').after('<p>Notice toc is changed in : \n<ul>\n<li>'+updatedTocsTitles.join('</li>\n<li> ')+'</li></p>');
}
if(updateInfo.length > 0){
var updatehtml = "";
for(var i=0;i<updateInfo.length;i++){
var uppdateTiddlertitle = updateInfo.eq(i).attr('title');
updatehtml += '!!Info to book '+bookshelf.getBookTitle((updateInfo.eq(i).attr('updateinfo').split('_'))[1])+'\n<<tiddler [['+updateInfo.eq(i).attr('title')+'##infolang_'+Emathbook.options.user.lang+']]>>\n';
}
loadscreen.find('p.currentState').append('<div id="updateinfo"><a id="updateinfobutton" href="javascript:;">Show update information</a><div style="display:none;" id="updateinformation"><p></p></div></div>');
loadscreen.find('#updateinfobutton').click(function(){
if(jQuery('#updateinformation').hasClass('ui-dialog-content')){
jQuery('#updateinformation').dialog("open");
}else{
var infoDialog = jQuery(this).parent().find('#updateinformation').dialog({
modal: true,
width:600,
height:600,
buttons: {
Ok: function() {
jQuery( this ).dialog( "close" );
}
}
});
wikify(updatehtml,infoDialog.find('p')[0],null,store.getTiddler(uppdateTiddlertitle));
}
});
}
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000); } } });
}
}else{
if(loadscreen.length == 0){
alert("No updates available!");
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('no updates available'));
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000); } } });
}
}
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').hide();
setTimeout("jQuery('body').find('#loadBookscreen').remove();",3000);
}
}
}
var response = jQuery.postCORS(updateurl, {"getContentUpdates":lastCheck.join(','), "bookName": bookids.join(','),"username":config.options.txtUserName ,"userkey":config.options.txtUserKey}, callback);
//testilogit.contentUpAjax={"getContentUpdates":lastCheck.join(','), "bookName": bookids.join(','),"username":config.options.txtUserName ,"userkey":config.options.txtUserKey};
}
Emathbook.systemUpdate = function(){
Emathbook.options.netconnection = true;
callback = function(data){
var loadscreen = jQuery('body #loadBookscreen');
if (response.status == 200){
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').show();
var serverTime = data.substring(0,data.indexOf('_')) || Emathbook.options.user.updates.lastSysCheck;
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
var hasSystemConfig = updelem.find('div[title][tags~="systemConfig"]').length > 0;
if (numberOfUpdates > 0){
var updateInfo = updelem.find('[updateinfo]');
store.importTiddlyWiki(data);
Emathbook.options.user.updates.lastSysCheck = serverTime;
Emathbook.options.saveUserSettings();
saveChanges();
if(loadscreen.length == 0){
alert(numberOfUpdates+" updates done!\n Browser will be refeshed.");
refreshElements(jQuery('#pageOneWrapper')[0]);
setTimeout('window.location.reload()',1500);
}else{
loadscreen.find('p.currentState').text((hasSystemConfig?EbookDictionary.localize('system updates done'):EbookDictionary.localize('system updates done').split('.')[0]));
if(updateInfo.length > 0){
var updatehtml = "";
for(var i=0;i<updateInfo.length;i++){
var uppdateTiddlertitle = updateInfo.eq(i).attr('title');
updatehtml += '<<tiddler [['+updateInfo.eq(i).attr('title')+'##infolang_'+Emathbook.options.user.lang+']]>>\n';
}
loadscreen.find('p.currentState').append('<div id="updateinfo"><a id="updateinfobutton" href="javascript:;">Show update information</a><div style="display:none;" id="updateinformation"><p></p></div></div>');
loadscreen.find('#updateinfobutton').click(function(){
if(jQuery('#updateinformation').hasClass('ui-dialog-content')){
jQuery('#updateinformation').dialog("open");
}else{
var infoDialog = jQuery(this).parent().find('#updateinformation').dialog({
modal: true,
width:600,
height:600,
buttons: {
Ok: function() {
jQuery( this ).dialog( "close" );
}
}
});
wikify(updatehtml,infoDialog.find('p')[0],null,store.getTiddler(uppdateTiddlertitle));
}
});
}
if(hasSystemConfig){
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout('window.location.reload()',1000); } } });
}else{
loadscreen.dialog(
{ buttons:
{ "Ok": function()
{
EbookDictionary.init();
refreshStyles('StyleSheet');
loadscreen.find('p.currentState').text(EbookDictionary.localize('checking contentupdates'));
Emathbook.getContentUpdates();
loadscreen.dialog({buttons:{}});
}
}
}
);
}
}
}else{
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('checking contentupdates'));
setTimeout("Emathbook.getContentUpdates()",500);
}
}
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').hide();
setTimeout("jQuery('body').find('#loadBookscreen').remove();",2000);
}
}
}
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {"updateURL": ""});
var updateurl = configs.updateURL;
var lastCheck = Emathbook.options.user.updates.lastSysCheck || upddata.lastSysCheck;
var response = jQuery.postCORS(updateurl, {"getSystemupdates":lastCheck, "username":config.options.txtUserName ,"userkey":config.options.txtUserKey}, callback);
//testilogit.sysupdata = response;
}
Emathbook.initBook = function(inittype){
var updatefunction ="";
this.initType=inittype;
switch(inittype){
case "author":
updatefunction = Emathbook.systemUpdate;
break;
case "course":
updatefunction = Emathbook.getCourseSystemUpdate;
break;
default:
break;
}
if(updatefunction !== "" && typeof(updatefunction)==="function"){
var loadDialog = jQuery('body').append('<div id="loadBookscreen" title="'+EbookDictionary.localize('Loading book')+'..."><p class="currentState"></p></div>').find('#loadBookscreen');
loadDialog.dialog({
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false
});
loadDialog.parent().find('.ui-dialog-titlebar-close').remove();
loadDialog.find('p.currentState').text(EbookDictionary.localize('Getting systemupdates'));
setTimeout(updatefunction,1000);
}else{
return true;
}
}
//}}}
/***
|Emathbook.js_admin|
|Version|1.1|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|E-math ebook ADMIN-tools|
!!!!!Revisions
<<<
20131006.1315 ''fix'' ''Version 1.1''
* fixed functionality
<<<
<<<
20131006.1315 ''Version 1.0''
* First version of Admin "tools"
<<<
!!!!!Code
***/
//{{{
Emathbook.sendSystemUpdate = function(tiddlerName,courseuppdatetype){
// courseuppdatetype -1 = nocoursesystemupdate type for coursesystemupdate :0= teacher 1=student 2=both
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tdata = store.getSaver().externalizeTiddler(store, store.getTiddler(tiddlerName));
var userName = config.options.txtUserName;
var userKey = config.options.txtUserKey;
var data = {
'sendUpdate': '1',
'author': userName,
'username': userName,
'userkey': userKey,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookName': EbookPages[0].ebook.bookid,
'systemUpdate': 1
};
if( store.getTiddler(tiddlerName).isTagged('authoronly')){
data['nocourseupdate'] = 1;
}else if(typeof(courseuppdatetype) !== "undefined"){
try{
switch(parseInt(courseuppdatetype)){
case -1:
data['nocourseupdate'] = 1;
break;
case 0:
case 1:
case 2:
data['updatetype'] = courseuppdatetype;
break;
default:
break;
}
}catch(e){
Alert('nocorseupdate');
data['nocourseupdate'] = 1;
}
}else if(!confirm('sending also to courseSystemUpdate?')){
Alert('systemUpdate not send!')
return false;
}
var response = jQuery.postCORS(updateurl, data, function(repdata){
testilogit.resp = repdata;
alert('Sent: ' + repdata);
});
}
Emathbook.adminSendUpdate = function(tiddlerName ,bookid, system){
//system: 0= content, 1=system(blocked), 2 = dictset, 3= modelsolution, 4= adminonly
if(system && system == 1){
alert("Use systemupdate!");
return false;
}
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var sendTiddler = store.getTiddler(tiddlerName);
var tdata = store.getSaver().externalizeTiddler(store, sendTiddler);
var userName = config.options.txtUserName;
var userKey = config.options.txtUserKey;
if(typeof(system)==="undefined"){
var systemupdate = 0;
} else {
var systemupdate = system;
}
if(sendTiddler.isTagged('modelsolution')){
systemupdate =3;
}else if(sendTiddler.isTagged('ebdictset')){
systemupdate = 2;
}
if(sendTiddler.isTagged('adminonly')){
systemupdate = 4;
}
var toBook = bookid || EbookPages[0].ebook.bookid;
var data = {
'sendUpdate': 1,
'author': userName,
'username': userName,
'userkey': userKey,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookName': toBook,
'systemUpdate': systemupdate
};
if (typeof(sendTiddler.fields.elementlanguage) !=="undefined"){
data.elemlanguage = sendTiddler.fields.elementlanguage;
}
var response = jQuery.postCORS(updateurl, data, function(repdata){
testilogit.resp = repdata;
alert('Sent: ' + repdata);
});
}
//}}}
/***
|Emathbook.js_author|
|Version|1.0|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|sendPageComment for E-math ebook|
!!!!!Revisions
<<<
20131006.1315 ''Version 1.0''
* Moved emath author-functions to own tiddler
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* emathbook.js
* Functionality of TiddlyWiki-ebook
*
* Petri Salmela
* Petri Sallasmaa
* 3.10.2011
*******************************************************************/
/*******************************************************
* Emathbook update functions
*******************************************************/
Emathbook.sendPageComment = function(tiddlerName){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tdata = store.getSaver().externalizeTiddler(store, store.getTiddler(tiddlerName));
var userName = config.options.txtUserName;
var now = new Date();
var nowtime = now.convertToYYYYMMDDHHMMSSMMM()
var data = {
'username' : config.options.txtUserName,
'userkey' : config.options.txtUserKey,
'sendPageComment': nowtime,
'author': userName,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookId': EbookPages[0].ebook.bookid
};
var response = jQuery.postCORS(updateurl, data, function(repdata){
if (repdata == 'Ok'){
alert("Your comment has been sent."); //localize
} else {
alert("Something went wrong. Try again later"); //localize
}
});
}
Emathbook.getPageComments = function(bookidlist, callback){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var defaultcomms = {"lastCheck":{}};
for (var i = 0; i<bookidlist.length; i++){
defaultcomms.lastCheck[bookidlist[i]] = 0;
}
var loadDialog = jQuery('body').append('<div id="loadBookscreen" title="'+EbookDictionary.localize('Loading...')+'..."><p class="currentState"></p></div>').find('#loadBookscreen');
loadDialog.dialog({
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false
});
loadDialog.parent().find('.ui-dialog-titlebar-close').remove();
loadDialog.find('p.currentState').text(EbookDictionary.localize('Loading...'));
var commdata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'pagecomments', defaultcomms);
var updateurl = configs.updateURL;
var lastchecklist = [];
for (var i = 0; i<bookidlist.length; i++){
lastchecklist.push(commdata.lastCheck[bookidlist[i]] || 0);
}
var lastCheck = lastchecklist.join(',');
var bookids = bookidlist.join(',');
var now = new Date();
var nowtime = now.convertToYYYYMMDDHHMMSSMMM();
var userName = config.options.txtUserName;
if (!callback){
callback = function(data){
testilogit.commentUp = response;
var loadscreen = loadDialog;
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_'));
data = data.substring(data.indexOf('_') + 1);
store.importTiddlyWiki(data);
for (var i = 0; i<bookidlist.length; i++){
commdata.lastCheck[bookidlist[i]] = serverTime;
}
DataTiddler.setData(Emathbook.config.userdatatiddler, 'pagecomments', commdata);
var commelem = jQuery(data);
var numberOfUpdates = commelem.find('div[title]').length;
loadscreen.find('p.currentState').text(EbookDictionary.localize('comments ready').format(numberOfUpdates, bookids));
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("refreshElements(jQuery('#pageTwo')[0]);jQuery('body').find('#loadBookscreen').remove();",1000); } } });
//alert(EbookDictionary.localize('comments ready').format(numberOfUpdates, bookids));
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').hide();
setTimeout("jQuery('body').find('#loadBookscreen').remove();",2000);
}
}
}
}
var response = jQuery.postCORS(updateurl, {"getPageComments":lastCheck, "bookId": bookids, "author": userName}, callback);
}
//}}}
/***
|''Name:''|Emathbook.js_course|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Course content and system send and update|
|''Version:''|1.0|
|''Date:''|May, 2013|
|''Source:''||
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130903.1202 ''fix''
* Use only one lastCourseSyscheck for all courses.
<<<
!!!!!Code
***/
//{{{
Emathbook.sendOfflineCourseContent= function(){
if(Emathbook.options.pages[0].courseid !=''){
// for now only student solutions are sended
var offlineTiddlers = store.getTaggedTiddlers('offlinesolution');
var backUpTiddlers = store.getTaggedTiddlers('backupthis');
var sendList = [];
for (var i=0;i<offlineTiddlers.length;i++){
sendList.push({'type':'5','tiddlerName':offlineTiddlers[i].title});
}
for (var i=0;i<backUpTiddlers.length;i++){
if(!backUpTiddlers[i].isTagged('offlinesolution')){
sendList.push({'type':'5','tiddlerName':backUpTiddlers[i].title});
}
}
if(sendList.length > 0){
Emathbook.getCourseUpdatesSilent(sendList);
}else if(jQuery('#bookclosedwindow').length > 0){
saveChanges();
setTimeout(function(){
jQuery('#bookclosingcontent').hide();
jQuery('#bookclosecontent').slideDown('slow');
},2000);
}
}
}
Emathbook.sendcourseContent = function(sendData){
if(typeof(sendData)=="object" && typeof(sendData.length)=="number"){
var sendItem = sendData.pop();
var sendItemtype = 'list';
} else {
var sendItem = sendData;
var sendItemtype = 'single';
}
if(typeof(sendItem) != "undefined"){
var courseId = Emathbook.options.pages[0].courseid;
var updateurl = Emathbook.options.courses[courseId].updateURL;
var sendedTiddler = store.getTiddler(sendItem.tiddlerName);
sendedTiddler.tags.remove('backupthis');
sendedTiddler.set(sendedTiddler.title,sendedTiddler.text, sendedTiddler.modifier, sendedTiddler.modified, sendedTiddler.tags, sendedTiddler.created, sendedTiddler.fields, sendedTiddler.creator);
saveChanges();
var tdata = store.getSaver().externalizeTiddler(store, sendedTiddler);
var data = {
'type' : sendItem.type,
'courseid' : courseId,
'username' : config.options.txtUserName,
'userkey' :config.options.txtUserKey,
'data' : tdata,
'ispublic' : (typeof(sendItem.isPublic)=="undefined" ? 0 : 1)
};
if(sendedTiddler.isTagged('solutiondata')){
data.ispublic = sendedTiddler.data().solution.ispublic ? 1 : 0;
}
if (sendedTiddler.fields.checknro){
data.checknro = sendedTiddler.fields.checknro;
}
if (typeof(sendItem.available) != "undefined"){
data.available = sendItem.available;
}
//alert(sendedTiddler.title);
//alert(sendedTiddler.tags);
var sendResponse = jQuery.postCORS(updateurl, data, function(repdata){
testilogit.resp = sendResponse;
if (sendResponse.status==200 ){
// alert(sendItemtype);
if(sendItemtype == 'single'){
setTimeout("Emathbook.getCourseUpdatesSilent()",1000);
}else{
if(sendData.length == 0){
setTimeout("Emathbook.getCourseUpdatesSilent()",1000);
}else{
Emathbook.getCourseUpdatesSilent(sendData);
}
}
}else{
//alert("moi");
sendedTiddler.tags.pushUnique('backupthis');
}
});
}else{
setTimeout("Emathbook.getCourseUpdatesSilent()",1000);
}
}
Emathbook.getCourseUpdatesSilent = function(callData){
var courseId = Emathbook.options.pages[0].courseid;
var callback = function(data){
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_')) || Emathbook.options.courses[courseId].lastCheck;
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
store.importTiddlyWiki(data);
Emathbook.options.courses[courseId].lastCheck = serverTime;
Emathbook.options.saveCourseSettings();
autoSaveChanges();
}
if(typeof(callData) != "undefined" && callData != []){
if(typeof(callData)=="object" && typeof(callData.length)=="number"){
if(callData.length == 0){return true;}
var originalTiddler = store.getTiddler(callData[callData.length-1].tiddlerName);
} else {
var originalTiddler = store.getTiddler(callData.tiddlerName);
}
if(originalTiddler.isTagged('offlinesolution')){
var originalTitle = originalTiddler.title;
var solutionTiddlerName =Emathbook.options.pages[0].courseid+"_"+config.options.txtUserName+"_solution_";
var i=0;
while(store.tiddlerExists(solutionTiddlerName+i)){i++;}
solutionTiddlerName += i;
var solutionTiddler = store.createTiddler(solutionTiddlerName);
originalTiddler.tags.remove('offlinesolution')
solutionTiddler.set(solutionTiddlerName, originalTiddler.text, originalTiddler.modifier, originalTiddler.modified, originalTiddler.tags, originalTiddler.created, originalTiddler.fields, originalTiddler.creator);
store.removeTiddler(originalTiddler.title);
autoSaveChanges();
jQuery('#pageOne ul.solutiontablist [tiddler="'+originalTitle+'"]').attr('tiddler',solutionTiddlerName).find('a').click();
if(typeof(callData)=="object" && typeof(callData.length)=="number"){
callData[callData.length-1].tiddlerName= solutionTiddlerName;
} else {
callData.tiddlerName = solutionTiddlerName;
}
}
Emathbook.sendcourseContent(callData);
}
}
if((typeof(callData) === "undefined" && jQuery('#bookclosedwindow').length > 0) || response.status != 200){
saveChanges();
jQuery('#bookclosedwindow').slideDown();
}
}
var postdata = {
'type' : 0,
'courseid' : courseId,
'username' : config.options.txtUserName,
'userkey' : config.options.txtUserKey,
'lastcheck' : (Emathbook.options.courses[courseId].lastCheck || 0)
};
var response = jQuery.postCORS(Emathbook.options.courses[courseId].updateURL, postdata, callback);
testilogit.updata = response;
}
Emathbook.getCourseSystemUpdate = function(){
Emathbook.options.netconnection = true;
var courseId = Emathbook.options.pages[0].courseid;
callback = function(data){
var loadscreen = jQuery('body #loadBookscreen');
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_')) || Emathbook.options.lastCourseSyscheck;
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
var updateInfo = updelem.find('[updateinfo]');
store.importTiddlyWiki(data);
Emathbook.options.lastCourseSyscheck = serverTime;
Emathbook.options.saveCourseSettings();
saveChanges();
if(loadscreen.length == 0){
alert(numberOfUpdates+" updates done!\n Browser will be refeshed.");
refreshElements(jQuery('#pageOneWrapper')[0]);
setTimeout('window.location.reload()',1500);
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('system updates done'));
if(updateInfo.length > 0){
var updatehtml = "";
for(var i=0;i<updateInfo.length;i++){
var uppdateTiddlertitle = updateInfo.eq(i).attr('title');
updatehtml += '<<tiddler [['+updateInfo.eq(i).attr('title')+'##infolang_'+Emathbook.options.user.lang+']]>>\n';
}
loadscreen.find('p.currentState').append('<div id="updateinfo"><a id="updateinfobutton" href="javascript:;">Show update information</a><div style="display:none;" id="updateinformation"><p></p></div></div>');
loadscreen.find('#updateinfobutton').click(function(){
if(jQuery('#updateinformation').hasClass('ui-dialog-content')){
jQuery('#updateinformation').dialog("open");
}else{
var infoDialog = jQuery(this).parent().find('#updateinformation').dialog({
modal: true,
width:600,
height:600,
buttons: {
Ok: function() {
jQuery( this ).dialog( "close" );
}
}
});
wikify(updatehtml,infoDialog.find('p')[0],null,store.getTiddler(uppdateTiddlertitle));
}
});
}
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout('window.location.reload()',1000); } } });
jQuery('body #loadBookscreen').parent().find('button').focus();
}
}else{
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('checking contentupdates'));
setTimeout("Emathbook.getCourseUpdates()",1000);
}
}
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000);
}
}
}
var senddata = {
"type":10,
"lastcheck":(Emathbook.options.lastCourseSyscheck || 0),
"courseid": courseId,
"username":config.options.txtUserName,
"userkey":config.options.txtUserKey
}
var response = jQuery.postCORS(Emathbook.options.courses[courseId].updateURL, senddata, callback);
testilogit.updata = response;
}
Emathbook.getCourseUpdates = function(){
var courseId = Emathbook.options.pages[0].courseid;
var extfiles = store.getTaggedTiddlers('ExternalTextFile');
for (var i=0; i<extfiles.length; i++){
var filepath = (extfiles[i].fields && extfiles[i].fields.filepath) || '';
if (filepath !== ''){
filepath = window.location.toString().replace(/[^\/]*.html/,'') + filepath;
filepath = getLocalPath(filepath);
saveFile(filepath, extfiles[i].text);
switch (extfiles[i].fields.filetype){
case 'javascript':
jQuery('body').append('<script type="text/javascript" src="'+extfiles[i].fields.filepath+'"></script>');
refreshElements(jQuery('#displayArea')[0], ['pageOne', 'pageTwo']);
break;
case 'css':
jQuery('head').append('<link type="text/css" rel="stylesheet" href="'+extfiles[i].fields.filepath+'"></link>');
break;
default:
break;
}
store.removeTiddler(extfiles[i].title);
}
}
var callback = function(data){
var loadscreen = jQuery('body #loadBookscreen');
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_')) || Emathbook.options.courses[courseId].lastCheck;
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
store.importTiddlyWiki(data);
Emathbook.options.courses[courseId].lastCheck = serverTime;
Emathbook.options.saveCourseSettings();
autoSaveChanges();
if(loadscreen.length == 0){
alert(numberOfUpdates+" updates done!");
refreshElements(jQuery('#pageOneWrapper')[0]);
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('contentupdates done'));
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000); } } });
jQuery('body #loadBookscreen').parent().find('button').focus();
}
}else{
if(loadscreen.length == 0){
alert("No updates available!");
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('no updates available'));
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000); } } });
jQuery('body #loadBookscreen').parent().find('button').focus();
}
}
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000);
}
}
}
var response = jQuery.postCORS(Emathbook.options.courses[courseId].updateURL, {"type":0,"lastcheck":(Emathbook.options.courses[courseId].lastCheck || 0), "courseid": courseId, "username":config.options.txtUserName ,"userkey":config.options.txtUserKey}, callback);
testilogit.updata = response;
}
//}}}
//{{{
/***************************************************
* EmathbookNumberline -class
***************************************************/
EmathbookNumberline = function(){
/*****************
* Constructor for numberline
*****************/
this.text = '';
this.startval = -10;
this.endval = 10;
this.points = {};
this.pointobjects = {};
this.ranges = {};
this.rangeobjects = {};
this.textobjects = {};
}
EmathbookNumberline.prototype.init = function(startval, endval){
/*****************
* Init numberline with starting and ending values.
*****************/
this.startval = startval;
this.endval = endval;
}
EmathbookNumberline.prototype.addPoint = function(name, xcoord, color, fillcolor, face, ptype){
/*****************
* Add point to numberline.
*****************/
if (typeof(ptype) == 'undefined'){
ptype = 'point';
}
if (ptype != 'point' && ptype != 'glider'){
return false;
}
if (typeof(color) == 'undefined'){
color = 'red';
}
if (typeof(fillcolor) == 'undefined'){
fillcolor = color;
}
if (typeof(face) == 'undefined'){
face = 'o';
}
var point = {xcoord: xcoord, color: color, fillcolor: fillcolor, face: face, ptype: ptype};
this.points[name] = point;
}
EmathbookNumberline.prototype.addGlider = function(name, xcoord, color, fillcolor, face){
/*****************
* Add point to numberline.
*****************/
this.addPoint(name, xcoord, color, fillcolor, face, 'glider');
}
EmathbookNumberline.prototype.addRange = function(name, rfrom, rto, color, rtype){
/*****************
* Add range to numberline.
*****************/
rtype = rtype || 'range';
var range = {from: rfrom, to: rto, color: color, rtype: rtype};
this.ranges[name] = range;
}
EmathbookNumberline.prototype.updatePoint = function(name, xcoord, color, fillcolor, face){
/*****************
* Update point on numberline.
*****************/
// TODO
this.board.elementByName[name]
}
EmathbookNumberline.prototype.create = function(element){
/*****************
* Create numberline into given html-element.
*****************/
var elemname = 'emathbooknumberline_';
var elemnumber = 0;
while (jQuery('#'+elemname+elemnumber).length > 0 && elemnumber < 1000){
elemnumber = elemnumber + 1;
}
if (elemnumber >= 1000){
jQuery(element).append('<div class="error">Error: Too many numberlines.</div>');
return false;
} else {
elemname = elemname + elemnumber;
}
jQuery(element).append('<div class="emathbooknumberline" id="'+elemname+'"></div>');
this.elementname = elemname;
this.draw();
}
EmathbookNumberline.prototype.update = function(elemname){
/*****************
* Update numberline into given html-element.
*****************/
this.draw(elemname);
}
EmathbookNumberline.prototype.draw = function(elemname){
/*****************
* Draw numberline into given html-element.
*****************/
if (typeof(elemname) == 'undefined'){
elemname = this.elementname;
}
if (typeof(elemname) == 'undefined' || !elemname.match(/^emathbooknumberline_[0-9]+$/) || jQuery('#'+elemname).length == 0){
// If given elemname is not required form or that element does not exist in dom.
return false;
}
var element = jQuery('#'+elemname);
element.empty();
var elemwidth = jQuery(element).width();
var elemheight = jQuery(element).height();
var tbbounds = 0.51*elemheight* (this.endval - this.startval) / elemwidth;
this.board = JXG.JSXGraph.initBoard(elemname, {boundingbox: [this.startval, tbbounds, this.endval, -tbbounds], axis:false, keepaspectratio: true, grid: false, showNavigation: false, showCopyright: false});
jQuery('#'+elemname+' svg').css('width','100%');
JXG.removeEvent(this.board.containerObj, 'mousewheel', this.board.mouseWheelListener, this.board);
JXG.removeEvent(this.board.containerObj, 'DOMMouseScroll', this.board.mouseWheelListener, this.board);
this.axis = this.board.create('axis', [[0,0],[1,0]], {strokeColor: 'red', shadow: true, fixed: true, ticks: false, grid: false, name:'axis'});
// this.axis.removeAllTicks();
this.board.createElement('ticks',[this.axis,5], {minorTicks:4, majorHeight:30, minorHeight: 10, strokeWidth: 2, drawZero:true});
// this.origo = this.board.create('point',[0,0], {strokeColor: 'black', fillColor: 'black', face: 'o', size: 2, shadow: true, name: 'O', fixed: true});
// for (var i = 0; i < this.points.length; i++){
for (var name in this.points){
var coords = [this.points[name].xcoord,0];
var isfixed = true;
if (this.points[name].ptype == 'glider'){
coords.push(this.axis);
isfixed = false;
}
this.pointobjects[name] = this.board.create(this.points[name].ptype, coords, {strokeColor: this.points[name].color, fillColor: this.points[name].fillcolor, face: this.points[name].face, shadow: true, name: name, fixed: isfixed});
}
for (var rname in this.ranges){
var rfrom = this.ranges[rname].from.replace(/,/g, '.');
var rto = this.ranges[rname].to.replace(/,/g, '.');
var rtype = this.ranges[rname].rtype;
var ypos = 0;
var firstarr = false;
var lastarr = false;
var swidth = 4;
if (rtype == 'length'){
ypos = -0.4*tbbounds;
firstarr = true;
lastarr = true;
swidth = 2;
}
var fromxpos = (''+parseFloat(rfrom) == rfrom ? parseFloat(rfrom) : 'X('+rfrom+')');
var toxpos = (''+parseFloat(rto) == rto ? parseFloat(rto) : 'X('+rto+')');
var coordsfrom = [fromxpos, ypos];
var coordsto = [toxpos, ypos];
this.rangeobjects[rname] = this.board.create('line', [coordsfrom, coordsto], {strokeColor: this.ranges[rname].color, name: rname, straightFirst: false, straightLast: false, strokeWidth: swidth, shadow: true, firstArrow: firstarr, lastArrow: lastarr, fixed: true});
var nlist = this;
if (rtype == 'length'){
var textxpos = (''+parseFloat(rfrom) == rfrom || ''+parseFloat(rto) == rto ? (parseFloat(rfrom) + parseFloat(rto))/2 : '(X('+rfrom+')+X('+rto+'))/2');
this.textobjects[rname+'_label'] = this.board.create('text',[textxpos, 2*ypos, function(){testilogit.tama=this; this.rfrom = this.rfrom || rfrom; this.rto = this.rto || rto; return (Math.round(10*Math.abs(nlist.pointobjects[this.rfrom].X() - nlist.pointobjects[this.rto].X())))/10;}], {display: 'html'});
this.textobjects[rname+'_label'].rfrom = rfrom;
this.textobjects[rname+'_label'].rto = rto;
}
}
testilogit.nline = this;
}
EmathbookNumberline.prototype.getobject = function(){
/*****************
* Return data of numberline.
*****************/
var jsondata = {};
jsondata.text = this.text;
jsondata.startval = this.startval;
jsondata.endval = this.endval;
jsondata.points = this.points;
return JSON.parse(JSON.stringify(jsondata));
}
EmathbookNumberline.prototype.setdata = function(setobj){
/*****************
* Set data of numberline.
*****************/
if (typeof(setobj) == 'string'){
try {
setobj = JSON.parse(setobj);
} catch (e) {
return false;
}
}
if (typeof(setobj) == 'object' &&
typeof(setobj.text) == 'string' &&
typeof(setobj.startval) == 'number' &&
typeof(setobj.endval) == 'number' &&
typeof(setobj.points) == 'object'){
this.text = setobj.text;
this.startval = setobj.startval;
this.endval = setobj.endval;
this.points = jQuery.extend({},setobj.points);
return true;
} else {
return false;
}
}
//}}}
Settings for Emathbook:
<<showData>>
<data>{"ebookpages":{"pageOne":{"currentpage":"front"},"pageTwo":{"currentpage":"front"}},"pagetwovisible":false}</data>
//{{{
config.macros.emathineqgraph = {
/******************************
* Show emath inequation graphs
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var eqtype = params[0] || '=';
var asign = params[1] || '+';
var roots = params[2] || '210';
var fname = params[3] || '';
var idnum = -1;
while (jQuery('#emathineqgraph_'+(++idnum)).length > 0){};
var emieqtext = '<html><div class="emathineqgraphwrapper" style="position: relative;"><div id="emathineqgraph_'+idnum+'"></div><div class="emathineqgraphshield" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0; z-index: 11;"></div></html>';
wikify(emieqtext, place, null, tiddler);
config.macros.emathineqgraph.ineq2ordGraphs('emathineqgraph_'+idnum, eqtype, asign, roots, fname);
},
ineq2ordGraphs: function (position, eqtype, asign, roots, fname)
{
var eqtypes = {'=': false, '<': false, '<=': false, '>': false, '>=': false, '!=': false};
if (!(eqtype in eqtypes)){
return false;
}
if (typeof(roots) === 'undefined'){
roots = '210';
}
if (typeof(asign) === 'undefined'){
asign = '+';
}
var $box = jQuery('#'+position);
$box.css({height: '250px', width: $box.width() + 'px', padding: '5px', position: 'relative'});
var boxwidth = 2+5*(roots.length);
var graphs = {
'+': {
'2': 'A2(1,0) invisible; B2(5,0) invisible; axis2=[A2 B2] nolabel; f2:(x-3)^2-1; P21(2,0) nolabel; P22(4,0) nolabel;',
'1': 'A1(1,0) invisible; B1(5,0) invisible; axis1=[A1 B1] nolabel; f1:(x-3)^2; P1(3,0) nolabel;',
'0': 'A0(1,0) invisible; B0(5,0) invisible; axis0=[A0 B0] nolabel; f0:(x-3)^2+1;',
'210': 'A2(1,0) invisible; B2(5,0) invisible; axis2=[A2 B2] nolabel; A1(6,0) invisible; B1(10,0) invisible; axis1=[A1 B1] nolabel; A0(11,0) invisible; B0(15,0) invisible; axis0=[A0 B0] nolabel; f2:(x-3)^2-1; f1:(x-8)^2; f0:(x-13)^2+1; P21(2,0) nolabel; P22(4,0) nolabel; P1(8,0) nolabel;'
},
'-': {
'2': 'A2(1,0) invisible; B2(5,0) invisible; axis2=[A2 B2] nolabel; f2:-(x-3)^2+1; P21(2,0) nolabel; P22(4,0) nolabel;',
'1': 'A1(1,0) invisible; B1(5,0) invisible; axis1=[A1 B1] nolabel; f1:-(x-3)^2; P1(3,0) nolabel;',
'0': 'A0(1,0) invisible; B0(5,0) invisible; axis0=[A0 B0] nolabel; f0:-(x-3)^2-1;',
'210': 'A2(1,0) invisible; B2(5,0) invisible; axis2=[A2 B2] nolabel; A1(6,0) invisible; B1(10,0) invisible; axis1=[A1 B1] nolabel; A0(11,0) invisible; B0(15,0) invisible; axis0=[A0 B0] nolabel; f2:-(x-3)^2+1; f1:-(x-8)^2; f0:-(x-13)^2-1; P21(2,0) nolabel; P22(4,0) nolabel; P1(8,0) nolabel;'
}
}
// Upwards opening
var intervals = {
'+': {
'>': {
'2': 'interv21=[A2 P21] nolabel; interv22=[P22 B2] nolabel;',
'1': 'interv11=[A1 P1] nolabel; interv12=[P1 B1] nolabel;',
'0': 'interv0=[A0 B0] nolabel;',
'210': 'interv21=[A2 P21] nolabel; interv22=[P22 B2] nolabel; interv11=[A1 P1] nolabel; interv12=[P1 B1] nolabel; interv0=[A0 B0] nolabel;'
},
'<': {
'2': 'interv21=[P21 P22] nolabel;',
'1': '',
'0': '',
'210': 'interv21=[P21 P22] nolabel;'
},
'=': {
'2': '',
'1': '',
'0': '',
'210': ''
},
'!=': {
'2': 'interv20=[A2 P21] nolabel; interv21=[P21 P22] nolabel; interv22=[P22 B2] nolabel;',
'1': 'interv11=[A1 P1] nolabel; interv12=[P1 B1] nolabel;',
'0': 'interv0=[A0 B0] nolabel;',
'210': 'interv20=[A2 P21] nolabel; interv22=[P22 B2] nolabel; interv11=[A1 P1] nolabel; interv12=[P1 B1] nolabel; interv0=[A0 B0] nolabel; interv21=[P21 P22] nolabel;'
}
}
}
intervals['+']['<='] = intervals['+']['<'];
intervals['+']['>='] = intervals['+']['>'];
// Downwards opening
intervals['-'] = {};
intervals['-']['>'] = intervals['+']['<'];
intervals['-']['<'] = intervals['+']['>'];
intervals['-']['='] = intervals['+']['='];
intervals['-']['!='] = intervals['+']['!=']
intervals['-']['<='] = intervals['-']['<'];
intervals['-']['>='] = intervals['-']['>'];
var oldoptions = JXG.Options;
JXG.Options = JXG.deepCopy(JXG.Options, {
elements: {fixed: true},
point: {showInfobox: false}
});
var board, construction = [];
board = JXG.JSXGraph.initBoard(position, {grid: false, boundingbox: [0,2,boxwidth,-2], keepaspectratio: true, axis: false, showNavigation: false, showCopyright: false});
construction.push(board.construct(graphs[asign][roots]));
construction.push(board.construct(intervals[asign][eqtype][roots]));
var allaxis = ['axis2', 'axis1', 'axis0'];
for (var i = 0; i < 3; i++){
try {
construction[0][allaxis[i]].setProperty({strokeColor: 'black'});
} catch (err) {}
}
switch (eqtype){
case '<':
case '>':
case '!=':
var dots = ['P21','P22','P1'];
for (var i = 0; i < 3; i++){
try {
construction[0][dots[i]].setProperty({fillColor: 'white'});
} catch (err) {}
}
break;
default:
break;
}
var intervalnames = ['interv0','interv11','interv12', 'interv20', 'interv21','interv22']
for (var i = 0; i < 6; i++){
try {
construction[1][intervalnames[i]].setProperty({strokeColor: 'red'});
} catch (err) {}
}
JXG.Options = oldoptions;
$box.append('<div class="emathieq_shield"></div>').find('.emathieq_shield').css({position: 'absolute', top: '0', bottom: '0', left: '0', right: '0', 'z-index': '11'});
return board;
}
}
//}}}
/***
|''Name:''|Emathslide-view.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Slideshow view tools for for E-math ebook|
|''Version:''|1.0|
|''Date:''|November 2, 2012|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130918.1140 ''start''
* Splitted from Emathslide.js
<<<
!!!!!Code
***/
//{{{
var EmathSlide = function(options, tiddlername){
// Class for showing a presentation.
this.options = jQuery.extend({
type: 'book', // 'book' / 'slidelist'
style: 'default',
},options);
this.type = this.options.type;
if (this.type === 'slidelist'){
this.init(options.slides);
this.tiddler = store.getTiddler(tiddlername);
this.current = 0;
}
}
EmathSlide.prototype.init = function(slides){
// Init slideshow with ebelements
this.slides = [];
for (var i = 0, length = slides.length; i < length; i++) {
var slide = {title: slides[i].title, slideelements: []};
for (var j = 0, l = slides[i].slideelements.length; j < l; j++) {
var element = new EbElement(slides[i].slideelements[j], false);
slide.slideelements.push(element);
}
this.slides.push(slide);
}
}
EmathSlide.prototype.start = function(index){
// Starts showing of the presentation.
if (typeof(index) !== 'number') {
index = 0;
}
if (this.type === 'slidelist') {
jQuery('#emathslideshowpresenter').remove();
jQuery('body').append('<div id="emathslideshowpresenter" class="bookpage emathbookslideview"></div>');
this.presenter = jQuery('#emathslideshowpresenter');
} else {
jQuery('#pageOne').addClass('emathbookslideview');
}
var slideshow = this;
var contenthtml = ['<div id="emathslide_control">',
'<div id="emathslide_counter"></div><ul>',
'<li><a href="javascript:;" class="emathslide_prev yellowgrad" title="Previous"><span>< Prev</span></a></li>',
'<li><a href="javascript:;" class="emathslide_next yellowgrad" title="Next"><span>Next ></span></a></li>',
'<li><a href="javascript:;" class="emathslide_stop redgrad" title="Stop"><span>Stop</span></a></li>',
'</ul></div>'].join('\n');
this.control = jQuery(contenthtml);
jQuery('body').addClass('emathslidemode').append(this.control);
// Put style-tag in its place if it's not there already.
if (jQuery('head style#emathslidestyle').length == 0){
jQuery('head').append('<style id="emathslidestyle" type="text/css">'+EmathSlide.strings['style']+'</style>');
}
// Decide the size of the screen and zoom fonts with proper class.
var width = jQuery(window).width();
var height = jQuery(window).height();
var size = Math.min(width, 1.6*height);
this.sizeclass = '';
if (size <= 800){
this.sizeclass = 'emslidetiny';
} else if (size <= 1024) {
this.sizeclass = 'emslidesmall';
} else if (size <= 1440) {
this.sizeclass = 'emslidemedium';
} else if (size <= 1920) {
this.sizeclass = 'emslidelarge';
} else {
this.sizeclass = 'emslideextralarge';
}
var bodyelem = jQuery('body').addClass(this.sizeclass);
// Bind clicks for control buttons.
this.control.find('a.emathslide_stop').click(function(e){
slideshow.stop();
});
this.control.find('a.emathslide_next').click(function(e){
slideshow.next();
});
this.control.find('a.emathslide_prev').click(function(e){
slideshow.prev();
});
// Bind key events.
jQuery(document).bind('keydown.emslide', function(e){
switch (e.which){
case 34:
//case 32:
slideshow.next();
e.preventDefault();
break;
case 33:
//case 8:
slideshow.prev();
e.preventDefault();
break;
case 27:
slideshow.stop();
break;
default:
break;
}
});
// Start from the asked slide (index) or else show the page number of the ebook.
if (this.type === 'slidelist'){
this.setSlide(index);
} else {
jQuery('#emathslide_counter').html(EbookPages[0].getNumberedTitle().split(' ')[0] || '');
}
}
EmathSlide.prototype.stop = function(){
// Stop the presentation and clean.
jQuery('body').removeClass('emathslidemode').removeClass(this.sizeclass);
jQuery('#emathslide_control').remove();
jQuery('head style#emathslidestyle').remove();
jQuery(document).unbind('keydown.emslide');
if (this.type === 'slidelist'){
//EbookPages[0].setPage(this.origPage);
}
jQuery('#emathslideshowpresenter').remove();
jQuery('#pageOne').removeClass('emathbookslideview');
}
EmathSlide.prototype.next = function(){
// Go to the next slide. Depends on whether we are using the book or clustom slideshow.
switch (this.type){
case 'book':
EbookPages[0].nextPage();
jQuery('#emathslide_counter').html(EbookPages[0].getNumberedTitle().split(' ')[0] || '');
break;
case 'slidelist':
this.nextSlide();
break;
default:
break;
}
}
EmathSlide.prototype.prev = function(){
// Go to the previous slide.
switch (this.type){
case 'book':
EbookPages[0].prevPage();
jQuery('#emathslide_counter').html(EbookPages[0].getNumberedTitle().split(' ')[0] || '');
break;
case 'slidelist':
this.prevSlide();
break;
default:
break;
}
}
EmathSlide.prototype.prevSlide = function(){
// Go to the previous slide of a custom slideshow.
if (this.current === 0){
return 0;
}
this.setSlide(this.current - 1);
return this.current;
}
EmathSlide.prototype.nextSlide = function(){
// Go to the next slide of a custom slideshow.
if (this.current === this.slides.length - 1){
return this.slides.length - 1;
}
this.setSlide(this.current + 1);
return this.current;
}
EmathSlide.prototype.setSlide = function(num){
// show the slide with number num.
this.current = num;
var currentSlide = this.slides[num];
this.presenter.empty();
var text = '';
if (currentSlide.title) {
text += '<html><h1 class="emathslide-title">' + currentSlide.title + '</h1></html>\n';
}
for (var i = 0; i < currentSlide.slideelements.length; i++){
switch (currentSlide.slideelements[i].type){
case 'page':
var chapid = EbookPages[0].ebook.getIdByTiddler(currentSlide.slideelements[i].data) || false;
//var title = '';
//if (chapid){
// title = (EbookPages[0].ebook.tocdict[chapid].alttitles
// && (EbookPages[0].ebook.tocdict[chapid].alttitles[Emathbook.options.pages[0].lang]))
// || EbookPages[0].ebook.tocdict[chapid].title || '';
//}
//text += '!'+title+'\n';
//text += '<<tiddler [['+currentSlide.slideelements[i].data+']]>>\n<<pageinit 0>>';
//this.pageOne.set('pageOne', text, config.options.txtUserName);
//refreshElements(jQuery('#pageOneWrapper')[0]);
text += '<<tiddler [['+currentSlide.slideelements[i].data+']]>>\n';
break;
case 'title':
text += '<html><h1 class="emathslide-title">' + currentSlide.slideelements[i].data + '</h1></html>\n';
break;
case 'element':
text += '<<ebookbox [[' + currentSlide.slideelements[i].data + ']]>>\n';
break;
case 'custom':
text += '{{emslideelementcustom{\n';
//text += '!' + currentSlide[i].data.title + '\n';
text += currentSlide.slideelements[i].data + '\n';
text += '}}}';
break;
default:
//text += elementFunctions['getWiki'+currentSlide.slideelements[i].type](currentSlide.slideelements[i].data, '')+'\n';
text += currentSlide.slideelements[i].getWiki()+'\n';
break;
}
}
wikify(text, this.presenter[0], null, this.tiddler);
//this.pageOne.set('pageOne', text, config.options.txtUserName);
//refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#emathslide_counter').html(this.current + 1 +'/' + this.slides.length);
// Show as step by step, if requested.
if(typeof(Emathbook.options.user.showstepbystep) !== "undefined" && Emathbook.options.user.showstepbystep){
try{
Emathbook.showStepByStep(this.presenter);
} catch (err) {}
}
}
// Some custom css for showing a slideshow.
EmathSlide.strings = {
style: ['/**** Styles for EmathSlide ****/',
'body.emathslidemode .emathbookslideview {position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 300; background-color: white; margin: 0!important; max-width: none; padding: 0 2em; overflow: auto;}',
'body.emathslidemode.emslidetiny .emathbookslideview {font-size: 140%;}',
'body.emathslidemode.emslidesmall .emathbookslideview {font-size: 160%;}',
'body.emathslidemode.emslidemedium .emathbookslideview {font-size: 200%;}',
'body.emathslidemode.emslidelarge .emathbookslideview {font-size: 250%;}',
'body.emathslidemode.emslideextralarge .emathbookslideview {font-size: 300%;}',
'body.emathslidemode #emathslide_control {position: fixed; top: 0; right: 10px; border-radius: 0 0 8px 8px; border: 1px solid black; border-top: none; background-color: #ffe; z-index: 301;}',
'body.emathslidemode #emathslide_control ul {list-style: none; margin: 4px; padding: 0;}',
'body.emathslidemode #emathslide_control ul li {display: inline-block; margin: 4px; padding: 0; min-width: 40px; text-align: center;}',
'body.emathslidemode #emathslide_control ul li a {display: block; margin: 0; padding: 0.5em; min-height: 20px; border: 2px solid black; border-radius: 0.5em; box-shadow: 0 0 4px black; color: black; font-size: 140%; font-weight: bold;}',
'body.emathslidemode .yellowgrad {background: rgb(254,252,234); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(254,252,234,1) 0%, rgba(241,218,54,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,1)), color-stop(100%,rgba(241,218,54,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fefcea\', endColorstr=\'#f1da36\',GradientType=0 ); /* IE6-9 */}',
'body.emathslidemode .redgrad {background: rgb(255,48,25); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(255,48,25,1) 0%, rgba(207,4,4,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,48,25,1)), color-stop(100%,rgba(207,4,4,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ff3019\', endColorstr=\'#cf0404\',GradientType=0 ); /* IE6-9 */}',
'body.emathslidemode #emathslide_control {',
'box-shadow: 4px 4px 4px rgba(0,0,0,0.5); opacity: 0.2;',
'background: rgb(235,241,246); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(235,241,246,1) 0%, rgba(171,211,238,1) 50%, rgba(137,195,235,1) 51%, rgba(213,235,251,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(235,241,246,1)), color-stop(50%,rgba(171,211,238,1)), color-stop(51%,rgba(137,195,235,1)), color-stop(100%,rgba(213,235,251,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(235,241,246,1) 0%,rgba(171,211,238,1) 50%,rgba(137,195,235,1) 51%,rgba(213,235,251,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(235,241,246,1) 0%,rgba(171,211,238,1) 50%,rgba(137,195,235,1) 51%,rgba(213,235,251,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(235,241,246,1) 0%,rgba(171,211,238,1) 50%,rgba(137,195,235,1) 51%,rgba(213,235,251,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(235,241,246,1) 0%,rgba(171,211,238,1) 50%,rgba(137,195,235,1) 51%,rgba(213,235,251,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ebf1f6\', endColorstr=\'#d5ebfb\',GradientType=0 ); /* IE6-9 */}',
'body.emathslidemode #emathslide_control:hover {opacity: 1;}',
'body.emathslidemode #emathslide_counter {display: block; min-width: 4em; min-height: 1.5em; margin: 0.5em; padding: 0.5em; text-align: center; font-weight: bold; border-radius: 0.5em; box-shadow: inset 2px 2px 2px rgba(0,0,0,0.5), inset -2px -2px 2px white; }',
'body.emathslidemode #emathslide_control a.emathslide_next:before {',
'content: "\\25b6"; content: "\\25ba"; padding-left: 0.2em; font-size: 130%; text-shadow: -1px -1px 1px black, 1px 1px 1px white;}',
'body.emathslidemode #emathslide_control a.emathslide_prev:before {',
'content: "\\25c0"; content: "\\25c4"; padding-right: 0.2em; font-size: 130%; text-shadow: -1px -1px 1px black, 1px 1px 1px white;}',
'body.emathslidemode #emathslide_control a.emathslide_stop:before {',
'content: "\\2716"; color: #eee; font-size: 130%; text-shadow: -1px -1px 1px black, 1px 1px 1px white;}',
'body.emathslidemode #emathslide_control a.emathslide_next:hover:before, body.emathslidemode #emathslide_control a.emathslide_prev:hover:before, body.emathslidemode #emathslide_control a.emathslide_stop:hover:before {color: #fff;}',
'body.emathslidemode #emathslide_control a.emathslide_next span, body.emathslidemode #emathslide_control a.emathslide_prev span, body.emathslidemode #emathslide_control a.emathslide_stop span {display: none;}',
'body.emathslidemode .ebookbox .sdbooktheory h1:before, body.emathslidemode .ebookbox .sdbookexample h1:before {border-radius:0.5em; box-shadow: inset 2px 2px 2px black, inset -2px -2px 2px white; padding: 0 0.5em; margin-right: 1em;}',
'body.emathslidemode .emslideelementcustom {margin: 2em 0;}',
'body.emathslidemode .emathbookslideview[lang="fi"] .ebookbox .sdbooktheory h1:before {content: "Teoria";}',
'body.emathslidemode .emathbookslideview[lang="en"] .ebookbox .sdbooktheory h1:before {content: "Theory";}',
'body.emathslidemode .emathbookslideview[lang="sv"] .ebookbox .sdbooktheory h1:before {content: "Teori";}',
'body.emathslidemode .emathbookslideview[lang="et"] .ebookbox .sdbooktheory h1:before {content: "Teooria";}',
'body.emathslidemode .emathbookslideview[lang="fi"] .ebookbox .sdbookexample h1:before {content: "Esimerkki";}',
'body.emathslidemode .emathbookslideview[lang="en"] .ebookbox .sdbookexample h1:before {content: "Example";}',
'body.emathslidemode .emathbookslideview[lang="sv"] .ebookbox .sdbookexample h1:before {content: "Exempel";}',
'body.emathslidemode .emathbookslideview[lang="et"] .ebookbox .sdbookexample h1:before {content: "Näide";}',
'.bookpage.emathbookslideview h1.ebooktitle {background-repeat: repeat-x; background-position: left top;}',
// sdeditor specific!
'#emathslideshowpresenter .structuredderivation .button.command_qededit {display: none;}',
].join('\n')
}
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.ebookSlideshow = {
/******************************
* Show ebookSlideshow-button
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var options;
if (params.length > 0 && store.tiddlerExists(params[0])){
var tname = params[0];
options = DataTiddler.getData(tname, 'slideshow0', null);
}
var sname = (options && options.name) || 'Slide';
var wtext = '<html><a href="javascript:;" class="slideshowbutton">'+sname+'</a></html>';
wikify(wtext, place, null, tiddler);
var button = jQuery(place).find('a.slideshowbutton').last().button().click(function(){
var aaa = new EmathSlide(options);
aaa.start();
});
}
}
}
//}}}
/***
|''Name:''|Emathslide.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Slideshow tools for for E-math ebook|
|''Version:''|1.0|
|''Date:''|November 2, 2012|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130918.1100 ''fix''
* Hide edit button of structured derivations that were copied from the book.
<<<
<<<
20130918.1140 ''change''
* Split the view -part to Emathslide-view.js
<<<
!!!!!Code
***/
//{{{
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.ebookSlideshowCreator = {
/*********************************
* Show the creator of slideshows
*********************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var num = 0;
while (jQuery('#emslidecrtr-'+num).length > 0){num++};
var wrapperName = 'emslidecrtr-'+num;
var html = '<div id="'+wrapperName+'"></div>';
jQuery(place).append(html).find('#'+wrapperName).emathslidecrtr();
}
}
}
(function($){
/**
* emathslidecrtr
* @param options
*/
$.fn.emathslidecrtr = function(options){
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on emathslidecrtr' );
return this;
}
}
var methods = {
init: function( options ){
var settings = $.extend({
}, options);
return this.each(function(){
var emslidecrtr = new EmathSlidecrtr(this, settings);
//testilogit.emslidecrtr = emslidecrtr;
emslidecrtr.init();
});
},
data: function(){
// Return the scores as {correct: <number>, total: <number>}
return this.eq(0).data('emathslidecrtr');
}
};
var EmathSlidecrtr = function(place, settings){
testilogit.sl = this;
this.place = $(place);
this.editmode = false;
this.lang = this.place.parents('[lang]').eq(0).attr('lang');
this.clipboard = [];
var htmlcontent = ['<div class="emslidecrtr-wrapper">',
'<h1 class="emslidecrtr-apptitle"></h1>',
'<div class="emslidecrtr-controlarea emslidecrtr-panel"><ul class="emslidecrtr-controllist"></ul><div class="emslidecrtr-controloptions"></div></div>',
'<div class="emslidecrtr-listarea"><h2 class="emslidecrtr-slidetitle"></h2><ul class="emslidecrtr-slidelist"></ul></div>',
'<div class="emslidecrtr-buttonpanel emslidecrtr-panel"><ul class="emslidecrtr-buttonlist"></ul><div class="emslidecrtr-optionarea"></div></div>',
'<div class="emslidecrtr-previewarea"></div>',
'</div>'].join('\n');
this.place.html(htmlcontent);
this.titlearea = this.place.find('.emslidecrtr-apptitle');
this.controlarea = this.place.find('.emslidecrtr-controlarea');
this.controlpanel = this.place.find('.emslidecrtr-controlarea ul.emslidecrtr-controllist');
this.controloptions = this.place.find('.emslidecrtr-controloptions');
this.slidetitle = this.place.find('.emslidecrtr-slidetitle');
this.slidelist = this.place.find('.emslidecrtr-slidelist');
this.previewarea = this.place.find('.emslidecrtr-previewarea');
this.buttonarea = this.place.find('.emslidecrtr-buttonpanel');
this.buttonpanel = this.place.find('.emslidecrtr-buttonpanel ul.emslidecrtr-buttonlist');
this.optionarea = this.place.find('.emslidecrtr-buttonpanel .emslidecrtr-optionarea');
// Put css in use.
$('head style#emathslidecrtrcss').remove();
$('head').append('<style id="emathslidecrtrcss" type="text/css">'+this.strings.css+'</style>')
}
EmathSlidecrtr.prototype.init = function(){
var button;
var emslidecrtr = this;
this.titlearea.html(this.localize('Slide creator'));
this.initControlarea();
this.initButtonpanel();
}
EmathSlidecrtr.prototype.initButtonpanel = function(){
var emslidecrtr = this;
this.buttonpanel.empty();
for (var button in this.panelButtons){
var pbutt = this.panelButtons[button];
var context = (this.panelButtons[button].context ? ' context="'+this.panelButtons[button].context+'"' : '');
var buttitle = this.localize(pbutt.text);
var butcontent = pbutt.icon || ('<span>'+this.localize(pbutt.text)+'</span>');
this.buttonpanel.append('<li'+context+'><a href="javascript:;" callfunc="'+button+'" class="emslidecrtr-button emslidecrtr-button-'+pbutt.text+'" title="'+buttitle+'">'+butcontent+'</a></li>');
this.buttonpanel.find('a.emslidecrtr-button').last().click(function(){
var callfunc = $(this).attr('callfunc');
emslidecrtr.panelButtons[callfunc].func.call(emslidecrtr);
});
}
}
EmathSlidecrtr.prototype.initControlarea = function(){
var emslidecrtr = this;
this.controlpanel.empty();
for (var button in this.controlButtons){
var cbutt = this.controlButtons[button];
var context = (this.controlButtons[button].context ? ' context="'+this.controlButtons[button].context+'"' : '');
var cbtitle = this.localize(cbutt.text);
var cbcontent = cbutt.icon || '<span>'+this.localize(cbutt.text)+'</span>';
this.controlpanel.append('<li'+context+'><a href="javascript:;" callfunc="'+button+'" class="emslidecrtr-button emslidecrtr-button-'+cbutt.text+'" title="'+cbtitle+'">'+cbcontent+'</a></li>');
this.controlpanel.find('a.emslidecrtr-button').last().click(function(){
var callfunc = $(this).attr('callfunc');
emslidecrtr.controlButtons[callfunc].func.call(emslidecrtr);
});
}
}
EmathSlidecrtr.prototype.initEditpanel = function($panel){
var emslidecrtr = this;
this.editButtons = [];
this.elementAdders = {};
var elementTypeTiddlers = store.getTaggedTiddlers('teacherAddElement');
for (var i=0; i < elementTypeTiddlers.length; i++) {
var addElement = elementTypeTiddlers[i].data('addElement');
this.editButtons.push(addElement);
this.elementAdders[addElement.elementType] = addElement;
}
for (var i = 0; i < this.editButtons.length; i++) {
if (typeof(elementFunctions[this.editButtons[i].addFunction]) === 'function') {
var title = EbookDictionary.localize(this.editButtons[i].elementType);
var content = (this.editButtons[i].icon || '<span>'+title+'</span>');
$panel.append('<li><a href="javascript:;" class="emslidecrtr-button add'+this.editButtons[i].elementType+'" buttonListNro="'+i+'" title="'+title+'">'+content+'</a></li>');
}
}
$panel.find('li a').click(function(){
var $currentpanel = $(this).parents('div.emslidecrtr-addherepanel');
if ($currentpanel.length > 0) {
var index = emslidecrtr.previewarea.find('div.emslidecrtr-addherepanel').index($currentpanel);
}
elementFunctions[emslidecrtr.editButtons[jQuery(this).attr('buttonListNro')].addFunction](emslidecrtr, index);
});
}
EmathSlidecrtr.prototype.initPastepanel = function($panel){
var emslidecrtr = this;
for (var pasteb in this.pasteButtons) {
var pastebutton = this.pasteButtons[pasteb];
var title = this.localize(pastebutton.text);
var content = (pastebutton.icon || '<span>'+title+'</span>');
$panel.append('<li><a href="javascript:;" class="emslidecrtr-button emslidecrtr-here-'+pasteb+'" callfunc="'+pasteb+'" title="'+title+'">'+content+'</a></li>');
}
$panel.find('a.emslidecrtr-button').click(function(){
var callfunc = $(this).attr('callfunc');
var $currentpanel = $(this).parents('div.emslidecrtr-addherepanel');
if ($currentpanel.length > 0) {
var index = emslidecrtr.previewarea.find('div.emslidecrtr-addherepanel').index($currentpanel);
} else {
var index = 0;
}
emslidecrtr.pasteButtons[callfunc].func.call(emslidecrtr, index);
emslidecrtr.preview(emslidecrtr.currentslide);
});
}
EmathSlidecrtr.prototype.setShowTitle = function(){
var emslidecrtr = this;
if (this.editmode) {
this.slidetitle.html('<span class="mathquill-textbox">'+this.slideshow.name+'</span');
this.slidetitle.find('.mathquill-textbox').mathquill('textbox');
this.slidetitle.find('textarea').bind('focusout.slides', function(){
emslidecrtr.slideshow.name = $(this).parents('.mathquill-textbox').eq(0).mathquill('latex').replace(/\$\$+/, '');
});
} else {
this.slidetitle.html(this.slideshow.name.replace(/\$([^\$]+)\$/g, '<span class="mathquill-embedded-latex">$1</span>'))
.find('.mathquill-embedded-latex:not(.mathquill-rendered-math)').mathquill();
}
}
EmathSlidecrtr.prototype.slidelistClear = function(){
this.slidelist.empty();
}
EmathSlidecrtr.prototype.slidelistAdd = function(num){
var emslidecrtr = this;
var title = this.getTitle(num);
this.slidelist.append('<li><a href="javascript:;" class="emslidecrtr-listitem" title="'+title+'"><span class="itemnum">'+(num+1)+'</span><span class="itemcontent">'+title.replace(/\$([^\$]+)\$/g, '<span class="mathquill-embedded-latex">$1</span>')+'</span></a><a href="javascript:;" class="emslidecrtr-addslide"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M12 5 l6 0 l0 6 l6 0 l0 6 l-6 0 l0 6 l-6 0 l0 -6 l-6 0 l0 -6 l6 0z" /></svg></a></li>');
this.slidelist.find('a.emslidecrtr-listitem').last().click(function(){
$(this).parents('ul').eq(0).find('li.currentslide').removeClass('currentslide');
var $item = $(this).parents('li').eq(0);
$item.addClass('currentslide');
var index = $item.index();
emslidecrtr.preview(index);
}).end().end()
.find('a.emslidecrtr-addslide').last().click(function(){
var $lielem = $(this).parents('li').eq(0);
var numpos = $lielem.index() + 1;
emslidecrtr.addSlide(numpos);
emslidecrtr.showSlidelist();
emslidecrtr.setFocus(numpos);
});
this.slidelist.find('.mathquill-embedded-latex:not(.mathquill-rendered-math)').mathquill();
}
EmathSlidecrtr.prototype.addSlide = function(numpos){
var newslide = {title: "New slide", slideelements: []};
this.slideshow.slides.splice(numpos, 0, newslide);
}
EmathSlidecrtr.prototype.setFocus = function(num){
this.slidelist.find('a.emslidecrtr-listitem').eq(num).click();
}
EmathSlidecrtr.prototype.addElement = function(ebelement, index){
var data = ebelement.getData();
if (typeof(index) === 'number') {
this.slideshow.slides[this.currentslide].slideelements.splice(index, 0, data);
} else {
this.slideshow.slides[this.currentslide].slideelements.push(data);
}
this.preview(this.currentslide);
}
EmathSlidecrtr.prototype.preview = function(num){
if (this.editmode) {
this.editPreview(num);
} else {
this.showPreview(num);
}
this.slidelist.find('.currentslide').removeClass('currentslide')
.end().find('li').eq(this.currentslide).addClass('currentslide');
}
EmathSlidecrtr.prototype.showPreview = function(num){
var text = '';
if (this.slideshow.type === 'slidelist'){
var slide = this.slideshow.slides[num];
text += '<html><h1 class="emathslide-title">' + slide.title + '</h1></html>\n';
for (var i = 0; i < slide.slideelements.length; i++){
switch (slide.slideelements[i].type){
case 'page':
text += '<<tiddler [['+slide.slideelements[i].data+']]>>\n<<pageinit 1>>';
break;
case 'element':
text += '<<ebookbox [[' + slide.slideelements[i].data + ']]>>\n';
break;
case 'title':
text += '<html><h1 class="emathslide-title">' + slide.slideelements[i].data + '</h1></html>\n';
break;
case 'custom':
text += '{{emslideelementcustom{\n';
//text += '!' + slide[i].data.title + '\n';
text += slide.slideelements[i].data + '\n';
text += '}}}';
default:
text += elementFunctions['getWiki'+slide.slideelements[i].type](slide.slideelements[i].data, '')+'\n';
break;
}
}
this.previewarea.empty();
var tiddler = store.getTiddler(this.tiddlerName);
wikify(text, this.previewarea[0], null, tiddler);
this.currentslide = num;
}
$('#contentWrapper').removeClass('elementselectmode');
}
EmathSlidecrtr.prototype.editPreview = function(num){
var emslidecrtr = this;
var text = '';
if (this.slideshow.type === 'slidelist') {
var slide = this.slideshow.slides[num];
this.previewarea.empty();
var tiddler = store.getTiddler(this.tiddlerName);
text = '<h1 class="emathslide-title"><span class="mathquill-textbox">'+slide.title+'</span></h1>';
this.previewarea.append(text);
this.previewarea.find('.mathquill-textbox:not(.mathquill-editable)').last()
.mathquill('textbox')
.find('textarea')
.bind('focusout.slides', function(){
var $mqelem = $(this).parents('.mathquill-textbox').eq(0);
var newtext = $mqelem.mathquill('latex').replace(/\$\$+/g, '');
if (newtext !== emslidecrtr.slideshow.slides[num].title) {
emslidecrtr.slideshow.slides[num].title = newtext;
emslidecrtr.showSlidelist();
}
});
this.previewarea.append('<div class="emslidecrtr-addherepanel"><ul class="emslidecrtr-addhereelements"></ul><ul class="emslidecrtr-addherepaste"></ul></div>');
this.initEditpanel(this.previewarea.find('ul.emslidecrtr-addhereelements').last());
this.initPastepanel(this.previewarea.find('ul.emslidecrtr-addherepaste').last());
for (var i = 0; i < slide.slideelements.length; i++) {
switch (slide.slideelements[i].type) {
case 'page':
text = '{{emslideelementeditable editelementtype'+slide.slideelements[i].type+'{\n';
text += '<html>\n<ul class="emslideelementbuttons"></ul></html>';
text += '<<tiddler [['+slide.slideelements[i].data+']]>>\n<<pageinit 1>>';
text += '}}}\n';
wikify(text, this.previewarea[0], null, tiddler);
break;
case 'element':
text = '{{emslideelementeditable editelementtype'+slide.slideelements[i].type+'{\n';
text += '<html>\n<ul class="emslideelementbuttons"></ul></html>';
text += '<<ebookbox [[' + slide.slideelements[i].data + ']]>>\n';
text += '}}}\n';
wikify(text, this.previewarea[0], null, tiddler);
break;
case 'title':
text = '<h1 class="emathslide-title"><span slideelement="'+i+'" class="mathquill-textbox">'+slide.slideelements[i].data+'</span></h1>';
this.previewarea.append(text);
this.previewarea.find('.mathquill-textbox:not(.mathquill-editable)').last()
.mathquill('textbox')
.find('textarea')
.bind('focusout.slides', function(){
var $mqelem = $(this).parents('.mathquill-textbox').eq(0);
var slideelement = parseInt($mqelem.attr('slideelement'));
var newtext = $mqelem.mathquill('latex').replace(/\$\$+/g, '');
if (newtext !== emslidecrtr.slideshow.slides[num].slideelements[slideelement].data) {
emslidecrtr.slideshow.slides[num].slideelements[slideelement].data = newtext;
emslidecrtr.showSlidelist();
}
});
break;
case 'custom':
text = '<div class="emslideelementcustom emslideelementeditable editelementtypecustom"><textarea slideelement="'+i+'">'+slide.slideelements[i].data+'</textarea></div>';
this.previewarea.append(text).find('textarea')
.bind('focusout', function(){
var slideelement = parseInt($(this).attr('slideelement'));
emslidecrtr.slideshow.slides[num].slideelements[slideelement].data = $(this).val();
});
break;
default:
var editmode = ' edit';
if (slide.slideelements[i].type === 'emfuncgraph') {
editmode = ' author';
}
text = '{{emslideelementeditable editelementtype'+slide.slideelements[i].type+'{\n';
text += '<html>\n<ul class="emslideelementbuttons"></ul></html>';
text += elementFunctions['getWiki'+slide.slideelements[i].type](slide.slideelements[i].data, editmode);
text += '}}}\n'
wikify(text, this.previewarea[0], null, tiddler);
break;
}
// Show element button panel.
var elbuttonlist = this.previewarea.find('.emslideelementbuttons').last();
for (var elbutton in this.elementButtons) {
var elbutt = this.elementButtons[elbutton];
var title = this.localize(elbutt.text);
var content = (elbutt.icon || '<span>'+title+'</span>');
elbuttonlist.append('<li><a href="javascript:;" callfunc="'+elbutton+'" class="emslidecrtr-button emslidecrtr-button-'+elbutt.text+'" title="'+title+'">'+content+'</a></li>');
}
elbuttonlist.find('a.emslidecrtr-button').click(function(){
var callfunc = $(this).attr('callfunc');
var thiselem = $(this).parents('.emslideelementeditable').eq(0);
emslidecrtr.elementButtons[callfunc].func.call(emslidecrtr, thiselem);
});
this.previewarea.append('<div class="emslidecrtr-addherepanel"><ul class="emslidecrtr-addhereelements"></ul><ul class="emslidecrtr-addherepaste"></ul></div>');
this.initEditpanel(this.previewarea.find('ul.emslidecrtr-addhereelements').last());
this.initPastepanel(this.previewarea.find('ul.emslidecrtr-addherepaste').last());
}
this.previewarea.find('ul.emslidecrtr-addhereelements').last().addClass('lastelementpanel');
this.previewarea.find('ul.emslidecrtr-addherepaste').last().addClass('lastpastepanel');
this.currentslide = num;
}
$('#contentWrapper').addClass('elementselectmode');
}
EmathSlidecrtr.prototype.getTitle = function(num){
// Return the title of the slide, if exists.
if (typeof(this.slideshow.slides[num].title) !== 'undefined'){
var title = this.slideshow.slides[num].title;
} else {
var title = '';
}
return title;
}
EmathSlidecrtr.prototype.localize = function(text){
var result = text;
if (this.dictionary[text] && this.dictionary[text][this.lang]){
result = this.dictionary[text][this.lang];
}
return result;
}
EmathSlidecrtr.prototype.getNewTiddler = function(){
var course = Emathbook.options.pages[0].courseid || 'A1';
var name = config.options.txtUserName;
var index = 0;
while (store.tiddlerExists(course+'_'+name+'_teacherelement_offline_'+index)) {
index++;
}
var tiddlerName = course+'_'+name+'_teacherelement_offline_'+index;
store.createTiddler(tiddlerName);
var newtiddler = store.getTiddler(tiddlerName);
newtiddler.set(tiddlerName, '', config.options.txtUserName, null, 'slideshow');
return tiddlerName;
}
EmathSlidecrtr.prototype.open = function(tiddlerName, showName){
if (typeof(showName) === 'undefined') {
showName = 'slideshow0';
}
var data = DataTiddler.getData(tiddlerName, showName, {});
//this.slideshow = jQuery.extend(true, {}, data);
this.slideshow = {
name: data.name,
dependbooks: jQuery.extend([], data.dependbooks),
type: data.type,
slides: []
};
for (var s = 0, slen = data.slides.length; s < slen; s++) {
var slideitem = data.slides[s];
var slide = {title: slideitem.title, slideelements: []};
for (var e = 0, elen = slideitem.slideelements.length; e < elen; e++) {
var elemdata = slideitem.slideelements[e];
var element = new EbElement(elemdata);
slide.slideelements.push(element);
}
this.slideshow.slides.push(slide);
}
this.setShowTitle();
if (this.slideshow.type === 'slidelist') {
this.showSlidelist();
}
this.tiddlerName = tiddlerName;
this.showname = showName;
this.previewarea.empty();
this.slidelist.find('a.emslidecrtr-listitem').eq(0).click();
}
EmathSlidecrtr.prototype.save = function(){
if (!store.tiddlerExists(this.tiddlerName)) {
store.createTiddler(this.tiddlerName);
var newtiddler = store.getTiddler(this.tiddlerName);
newtiddler.set(this.tiddlerName, '', config.options.txtUserName, null, 'slideshow');
}
DataTiddler.setData(this.tiddlerName, this.showname, this.slideshow, {});
}
EmathSlidecrtr.prototype.showSlidelist = function(){
this.slidelistClear();
for (var i = 0, length = this.slideshow.slides.length; i < length; i++) {
this.slidelistAdd(i);
}
}
EmathSlidecrtr.prototype.panelButtons = {
'previous': {
'text': 'previous',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M22 25 l-15 -10 l15 -10z" /></svg>',
'func': function(){
this.preview(Math.max(this.currentslide - 1, 0));
}
},
'next': {
'text': 'next',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M8 5 l15 10 l-15 10z" /></svg>',
'func': function(){
this.preview(Math.min(this.currentslide + 1, this.slideshow.slides.length-1));
}
},
'remove': {
'text': 'remove',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M5 5.5 l7 -2 l-0.2 -1 l2 -0.4 l0.2 1 l7 -2 l0.6 2 l-16 4.4 z M7 8 l16 0 l-3 20 l-10 0z M9 10 l2 15 l2 0 l-1 -15z M13.5 10 l0.5 15 l2 0 l0.5 -15z M21 10 l-3 0 l-1 15 l2 0z" /></svg>',
'context': 'edit',
'func': function(){
var emslidecrtr = this;
if (typeof(this.currentslide) === 'number' && confirm(this.localize('are you sure'))) {
var num = this.currentslide;
this.slideshow.slides.splice(num, 1);
if (this.slideshow.slides.length <= num) {
num = num-1;
}
this.showSlidelist();
this.setFocus(num);
}
}
},
'paste': {
'text': 'clipboard',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-clipboard"><path style="stroke: none;" d="M2 2 l2 0 l0 -1 l20 0 l0 1 l2 0 l0 23 l-24 0 z M5 2 l0 4 l18 0 l0 -4 z M10 0 l8 0 l0 4 l-8 0 z" /></svg>',
'context': 'edit',
'func': function(){
var emslidecrtr = this;
var html = ['<fieldset><legend>' + this.localize('clipboard') + '</legend>'];
for (var clip = 0; clip < this.clipboard.length; clip++) {
html.push('<input type="checkbox" name="emslidecrtr-clippaste" id="emslidecrtr-clippaste-'+clip+'" value="'+clip+'" checked="checked" /><label for="emslidecrtr-clippaste-'+clip+'">'+this.clipboard[clip].type+'</label><br />');
}
html.push('<a href="javascript:;" class="emslidecrtr-button" id="emslidecrtr-optioncancel">'+this.localize('close')+'</a>');
if (this.clipboard.length > 0) {
//html.push('<a href="javascript:;" class="emslidecrtr-button" id="emslidecrtr-optionpaste">'+this.localize('paste')+'</a>');
html.push('<a href="javascript:;" class="emslidecrtr-button" id="emslidecrtr-optionclear">'+this.localize('clear')+'</a>');
}
html.push('</fieldset>');
html = html.join('\n');
this.buttonarea.addClass('optionson');
this.previewarea.addClass('emslidecrtr-pastemode');
this.optionarea.html(html)
//.find('a#emslidecrtr-optionpaste').click(function(){
// var slidelist = emslidecrtr.slideshow.slides[emslidecrtr.currentslide].slideelements;
// for (var clip = 0; clip < emslidecrtr.clipboard.length; clip++) {
// if (emslidecrtr.optionarea.find('input#emslidecrtr-clippaste-'+clip+':checked').length > 0) {
// slidelist.push(emslidecrtr.clipboard[clip]);
// }
// }
// emslidecrtr.buttonarea.removeClass('optionson');
// emslidecrtr.optionarea.empty();
// emslidecrtr.previewarea.removeClass('emslidecrtr-pastemode');
// emslidecrtr.preview(emslidecrtr.currentslide);
//}).end()
.find('a#emslidecrtr-optionclear').click(function(){
var slidelist = emslidecrtr.slideshow.slides[emslidecrtr.currentslide].slideelements;
for (var clip = emslidecrtr.clipboard.length-1; clip > -1 ; clip--) {
if (emslidecrtr.optionarea.find('input#emslidecrtr-clippaste-'+clip+':checked').length > 0) {
emslidecrtr.clipboard.splice(clip, 1);
}
}
emslidecrtr.buttonarea.removeClass('optionson');
emslidecrtr.optionarea.empty();
emslidecrtr.previewarea.removeClass('emslidecrtr-pastemode');
emslidecrtr.preview(emslidecrtr.currentslide);
}).end()
.find('a#emslidecrtr-optioncancel').click(function(){
emslidecrtr.previewarea.find('.emslidecrtr-pastehere').remove();
emslidecrtr.buttonarea.removeClass('optionson');
emslidecrtr.optionarea.empty();
emslidecrtr.previewarea.removeClass('emslidecrtr-pastemode');
});
//this.previewarea.find('.emslideelementeditable').before('<div class="emslidecrtr-pastehere"><a href="javascript:;" class="emslidecrtr-button">'+this.localize('paste')+'</a></div>');
//this.previewarea.append('<div class="emslidecrtr-pastehere"><a href="javascript:;" class="emslidecrtr-button">'+this.localize('paste')+'</a></div>');
//this.previewarea.find('.emslidecrtr-pastehere a').click(function(){
// var places = emslidecrtr.previewarea.find('.emslidecrtr-pastehere a');
// var index = places.index($(this));
// var slidelist = emslidecrtr.slideshow.slides[emslidecrtr.currentslide].slideelements;
// for (var clip = emslidecrtr.clipboard.length-1; clip > -1 ; clip--) {
// if (emslidecrtr.optionarea.find('input#emslidecrtr-clippaste-'+clip+':checked').length > 0) {
// slidelist.splice(index, 0, jQuery.extend(true, emslidecrtr.clipboard[clip], {}));
// }
// }
// emslidecrtr.buttonarea.removeClass('optionson');
// emslidecrtr.optionarea.empty();
// emslidecrtr.previewarea.removeClass('emslidecrtr-pastemode');
// emslidecrtr.preview(emslidecrtr.currentslide);
//});
}
},
}
EmathSlidecrtr.prototype.controlButtons = {
'new': {
'text': 'new slideshow',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-new"><path style="stroke: none;" d="M6 3 l13 0 l7 7 l0 18 l-20 0 z m1 1 l0 23 l18 0 l0 -16 l-7 0 l0 -7 z m7 9 l4 0 l0 4 l4 0 l0 4 l-4 0 l0 4 l-4 0 l0 -4 l-4 0 l0 -4 l4 0z" /></svg>',
'func': function(){
if (typeof(this.tiddlerName) !== 'undefined') {
this.save();
}
this.tiddlerName = this.getNewTiddler();
this.showname = this.showname || 'slideshow0';
this.slideshow = {
"name": "New Name",
"dependbooks": [],
"type": "slidelist",
"slides": [
{
"title": "New title",
"slideelements": []
}
]
};
this.setShowTitle();
this.showSlidelist();
this.place.addClass('emslides-isopen');
this.setFocus(0);
}
},
'open': {
'text': 'open',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-open"><path style="stroke: none;" d="M2 6 l8 0 l1 3 l14 0 l0 1 -19 3 l-5 10z m1 19 l5 -10 l20 -2 l-5 10z" /></svg>',
'func': function(){
var emslidecrtr = this;
if (this.slideshow) {
this.controlarea.find('a.emslidecrtr-button-view').click();
}
var allslideshows = store.getTaggedTiddlers('slideshow');
var html = [
'<a href="javascript:;" class="emslidecrtr-button" id="emslidecrtr-opencancel">'+this.localize('cancel')+'</a>',
'<fieldset><legend>' + this.localize('choose presentation') + '</legend>',
'<ul class="emslidecrtr-openlist">'
];
for (var sshow = 0; sshow < allslideshows.length; sshow++) {
var tname = allslideshows[sshow].title;
var data = allslideshows[sshow].data('slideshow0', {});
var sname = data.name || '';
var size = '';
if (data.slides){
size = ' ('+data.slides.length+')';
}
html.push('<li><a href="javascript:;" tname="'+tname+'">'+sname.replace(/\$([^\$]+)\$/g, '<span class="mathquill-embedded-latex">$1</span>')+size+'</a></li>');
}
html.push('</ul></fieldset>');
this.controlarea.addClass('optionson');
this.controloptions.html(html.join('\n'))
.find('#emslidecrtr-opencancel').click(function(){
emslidecrtr.controlarea.removeClass('optionson');
emslidecrtr.controloptions.empty();
})
.end().find('ul.emslidecrtr-openlist li a').click(function(){
emslidecrtr.editmode = false;
emslidecrtr.place.removeClass('emslides-editmode');
emslidecrtr.place.addClass('emslides-isopen');
var tname = $(this).attr('tname');
emslidecrtr.open(tname);
emslidecrtr.controlarea.removeClass('optionson');
emslidecrtr.controloptions.empty();
})
.end().find('.mathquill-embedded-latex:not(.mathquill-rendered-math)').mathquill();
}
},
'save': {
'text': 'save',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-save"><path style="stroke: none;" d="M2 2 l22 0 l4 4 l0 22 l-26 0z m6 2 l0 7 l14 0 l0 -7z m9 1 l3 0 l0 5 l-3 0z m-12 9 l0 12 l20 0 l0 -12z" /></svg>',
'context': 'isopen',
'func': function(){
if (typeof(this.tiddlerName) !== 'undefined') {
this.save();
}
}
},
'edit': {
'text': 'edit',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-edit"><path style="stroke: none;" d="M16 2 l4 -1 l4 2 l1 4 l-10 15 l-10 5 l2 -11 z m-8.5 15.5 l-1.5 6 l1.8 1.5 l6.7 -3.3 l-1.5 -2 l-3 -2 z m11.5 -15.5 l-10 15 l1 0.5 l10 -15 z m4 2 l-10 15 l0.5 1 l10 -15 z" /></svg>',
'context': 'isopen',
'func': function(){
var emslidecrtr = this;
this.editmode = true;
this.place.addClass('emslides-editmode');
this.setShowTitle();
this.preview(this.currentslide);
$('#ebcopylistener').remove();
this.place.append('<div id="ebcopylistener"></div>');
$('#ebcopylistener').bind('ebcopypageelement', function(event, data){
emslidecrtr.clipboard.push(data);
});
EbookPages[0].setPage(EbookPages[0].currentpage);
}
},
'view': {
'text': 'view',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-view"><path style="stroke: none;" d="M3 15 a15 20 0 0 1 24 0 a15 20 0 0 1 -24 0 z m1 0 a14 17 0 0 0 22 0 a14 17 0 0 0 -22 0 z m5 0 a6 6 0 1 1 0 0.01z m2 -2 a2 2 0 1 0 0 -0.01z" /></svg>',
'context': 'isopen',
'func': function(){
this.editmode = false;
this.place.removeClass('emslides-editmode');
this.setShowTitle();
this.preview(this.currentslide);
$('#ebcopylistener').remove();
EbookPages[0].setPage(EbookPages[0].currentpage);
}
},
'show': {
'text': 'show',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-presentation"><path style="stroke: none;" d="M3 3 l24 0 l0 15 l-24 0 z m1 1 l0 13 l22 0 z m9 -1 l0 -2 l4 0 l0 2 z m0 15 l4 0 l0 8 l5 3 l-2 0 l-5 -3 l-5 3 l-2 0 l5 -3" /></svg>',
'context': 'isopen',
'func': function(){
var index = this.slidelist.find('li.currentslide').index();
var sshow = new EmathSlide(this.slideshow, this.tiddlerName);
sshow.start(index);
}
}
}
EmathSlidecrtr.prototype.pasteButtons = {
'paste': {
'text': 'paste',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M2 2 l2 0 l0 -1 l20 0 l0 1 l2 0 l0 6 l-16 0 l0 17 l-8 0 z M5 2 l0 4 l18 0 l0 -4 z M10 0 l8 0 l0 4 l-8 0 z M11 9 l20 0 l0 14 l-7 7 l-13 0 z M12 10 l0 19 l11 0 l0 -6 l6 0 l0 -13 z" /></svg>',
'func': function(index){
var emslidecrtr = this;
var slides = emslidecrtr.slideshow.slides[emslidecrtr.currentslide].slideelements;
if (emslidecrtr.clipboard.length > 0) {
var allinputs = emslidecrtr.optionarea.find('input[type="checkbox"]');
var selected = emslidecrtr.optionarea.find('input[type="checkbox"]:checked');
if (selected.length > 0) {
for (var i = selected.length - 1; i > -1; i--) {
var selindex = allinputs.index(selected.eq(i));
var copyfrom = emslidecrtr.clipboard[selindex];
if (emslidecrtr.elementAdders[copyfrom.type]) {
elementFunctions[emslidecrtr.elementAdders[copyfrom.type].addFunction](emslidecrtr, index, copyfrom.data);
} else {
slides.splice(index, 0, emslidecrtr.clipboard[selindex]);
}
}
} else {
var copyfrom = emslidecrtr.clipboard[emslidecrtr.clipboard.length-1];
if (emslidecrtr.elementAdders[copyfrom.type]) {
elementFunctions[emslidecrtr.elementAdders[copyfrom.type].addFunction](emslidecrtr, index, copyfrom.data);
} else {
slides.splice(index, 0, emslidecrtr.clipboard[emslidecrtr.clipboard.length-1]);
}
}
}
emslidecrtr.preview(emslidecrtr.currentslide);
}
}
}
EmathSlidecrtr.prototype.elementButtons = {
'cut': {
'text': 'cut',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><ellipse stroke="black" style="fill: none;" cx="6" cy="10" rx="5" ry="3" /><ellipse stroke="black" style="fill: none;" cx="6" cy="20" rx="5" ry="3" /><path style="stroke: none;" d="M7 13 l20 7 q-10 2 -15 -6 z" /><path style="stroke: none;" d="M7 17 l20 -7 q-10 -2 -15 6 z" /></svg>',
'func': function(thiselem){
var elements = this.previewarea.find('.emslideelementeditable');
var index = elements.index(thiselem);
this.clipboard = this.clipboard.concat(this.slideshow.slides[this.currentslide].slideelements.splice(index, 1));
this.preview(this.currentslide);
}
},
'copy': {
'text': 'copy',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M2 2 l18 0 l0 6 l-12 0 l0 17 l-6 0 z M10 10 l8 0 l0 10 l10 0 l0 10 l-18 0 z M20 10 l8 8 l-8 0 z" />/svg>',
'func': function(thiselem){
var elements = this.previewarea.find('.emslideelementeditable');
var index = elements.index(thiselem);
this.clipboard = this.clipboard.concat(this.slideshow.slides[this.currentslide].slideelements.slice(index, index+1));
}
},
'remove': {
'text': 'remove',
'icon': '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon"><path style="stroke: none;" d="M5 5.5 l7 -2 l-0.2 -1 l2 -0.4 l0.2 1 l7 -2 l0.6 2 l-16 4.4 z M7 8 l16 0 l-3 20 l-10 0z M9 10 l2 15 l2 0 l-1 -15z M13.5 10 l0.5 15 l2 0 l0.5 -15z M21 10 l-3 0 l-1 15 l2 0z" /></svg>',
'func': function(thiselem){
var elements = this.previewarea.find('.emslideelementeditable');
var index = elements.index(thiselem);
this.slideshow.slides[this.currentslide].slideelements.splice(index, 1);
this.preview(this.currentslide);
}
},
}
EmathSlidecrtr.prototype.dictionary = {
'Slide creator': {
'en': 'Slides tool',
'fi': 'Esitystyökalu',
'sv': 'Presenterare',
'et': 'Esitlus'
},
'open': {
'en': 'Open',
'fi': 'Avaa',
'sv': 'Öppna',
'et': 'Avage'
},
'save': {
'en': 'Save',
'fi': 'Tallenna',
'sv': 'Spara',
'et': 'Salvesta'
},
'new slideshow': {
'en': 'New',
'fi': 'Uusi',
'sv': 'Ny'
},
'add': {
'en': 'Add',
'fi': 'Lisää',
'sv': 'Add',
'et': 'Add'
},
'remove': {
'en': 'Remove',
'fi': 'Poista'
},
'cut': {
'en': 'Cut',
'fi': 'Leikkaa'
},
'paste': {
'en': 'Paste',
'fi': 'Liitä'
},
'clear': {
'en': 'Clear',
'fi': 'Tyhjennä'
},
'close': {
'en': 'Close',
'fi': 'Sulje'
},
'clipboard': {
'en': 'Clipboard',
'fi': 'Leikepöytä'
},
'edit': {
'en': 'Edit',
'fi': 'Muokkaa'
},
'view': {
'en': 'View',
'fi': 'Näytä'
},
'next': {
'en': 'Next',
'fi': 'Seuraava',
'sv': 'Next',
'et': 'Next'
},
'previous': {
'en': 'Previous',
'fi': 'Edellinen',
'sv': 'Previous',
'et': 'Previous'
},
'before': {
'en': 'before',
'fi': 'ennen',
'sv': 'före',
'et': 'before'
},
'after': {
'en': 'after',
'fi': 'jälkeen',
'sv': 'efter',
'et': 'after'
},
'ok': {
'en': 'OK',
'fi': 'OK',
'sv': 'OK',
'et': 'OK'
},
'cancel': {
'en': 'Cancel',
'fi': 'Peruuta',
'sv': 'cancel',
'et': 'cancel'
},
'choose presentation': {
'en': 'Choose presentation',
'fi': 'Valitse esitys'
},
'show': {
'en': 'Show',
'fi': 'Esitä'
},
'book': {
'en': 'Book',
'fi': 'Kirja',
'sv': 'Boken',
'et': 'Raamat'
},
'are you sure': {
'en': 'Are you sure?',
'fi': 'Oletko varma?'
}
}
EmathSlidecrtr.prototype.strings = {
css: [
'#tiddlerDisplay .emslidecrtr-wrapper {margin-top: 80px;}',
'.emslidecrtr-wrapper {position: absolute; top: 0; left: 0; right: 0; padding: 0.5em; background: #999;}',
'.emslidecrtr-wrapper h1.emslidecrtr-apptitle {margin: 0; padding: 0.2em; color: white; text-shadow: -1px -1px 3px black, 1px 1px 3px black; border-bottom: 2px solid white;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea {border-radius: 0.5em; min-height: 1em; margin: 0.5em 0 -30px 1em; border: none; box-shadow: none; background: transparent;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea ul.emslidecrtr-controllist {margin: 0; padding: 0; list-style: none;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea ul.emslidecrtr-controllist li {margin: 0 0.2em; padding: 0; display: inline-block;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea.optionson ul.emslidecrtr-controllist {display: none;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea.optionson .emslidecrtr-controloptions {display: block;}',
'.emslidecrtr-wrapper .emslidecrtr-listarea {border: 1px solid black; border-radius: 0.5em; min-height: 1em; margin: 0.5em 0 1.5em 0; background: white; padding-top: 20px; box-shadow: 10px 10px 30px rgba(0,0,0,0.5);}',
'.emslidecrtr-wrapper .emslidecrtr-controloptions {display: none; padding: 0.2em; margin-bottom: 40px; background-color: rgba(255,255,255,0.5); border-radius: 4px;}',
'.emslidecrtr-wrapper .emslidecrtr-controloptions ul.emslidecrtr-openlist {margin: 0.2em; padding: 0; max-height: 8em; overflow-y: scroll;}',
'.emslidecrtr-wrapper .emslidecrtr-controloptions ul.emslidecrtr-openlist li {margin: 0.2em; margin-left: 1.2em; padding: 0;}',
'.emslidecrtr-wrapper .emslidecrtr-previewarea {border: 1px solid black; border-radius: 0.5em; min-height: 1em; margin: 0.5em 0; padding: 0.3em 0.3em 20px 0.3em; overflow-x: hidden; overflow-y: auto; font-size: 80%; background: white; box-shadow: 10px 10px 30px rgba(0,0,0,0.5);}',
'.emslidecrtr-wrapper .emslidecrtr-previewarea .emslideelementeditable {margin: 1em 0; position: relative;}',
'.emslidecrtr-wrapper .emslidecrtr-previewarea .emslideelementeditable textarea {box-sizing: border-box; -moz-box-sizing: border-box; width: 100%; min-height: 10em; border: 1px solid #aaa; padding: 0.5em; box-shadow: 2px 2px 4px rgba(0,0,0,0.3);}',
'.emslides-editmode .emslidecrtr-previewarea.emslidecrtr-pastemode .emslideelementeditable:hover {background-color: white; border: 1px solid transparent; box-shadow: none;}',
'.emslides-editmode .emslidecrtr-previewarea.emslidecrtr-pastemode .emslideelementeditable:hover ul.emslideelementbuttons {display: none;}',
'.emslides-editmode .emslidecrtr-previewarea.emslidecrtr-pastemode .emslidecrtr-pastehere {text-align: right; background-color: #f8f8f8; border: 1px solid black; border-radius: 3px; height: 6px;}',
'.emslides-editmode .emslidecrtr-previewarea.emslidecrtr-pastemode .emslidecrtr-pastehere a.emslidecrtr-button {margin-top: -13px;}',
'.emslides-editmode .emslidecrtr-previewarea.emslidecrtr-pastemode .emslidecrtr-pastehere:hover {background-color: #e8e8e8;}',
'.emslides-editmode .emslidecrtr-previewarea .mathquill-textbox.mathquill-editable,',
'.emslides-editmode .emslidecrtr-slidetitle .mathquill-textbox.mathquill-editable {display: block;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel { border-radius: 0.5em; min-height: 1em; margin: 0 0 -2em 1em; border: none; box-shadow: none; background: transparent;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel ul {margin: 0; padding: 0; list-style: none;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel.optionson ul {display: none;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel ul li {margin: 0; padding: 0; display: inline-block;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel ul li[context="edit"] {display: none;}',
'.emslides-editmode .emslidecrtr-wrapper .emslidecrtr-buttonpanel ul li[context="edit"] {display: inline-block;}',
'.emslidecrtr-wrapper .emslidecrtr-controlarea ul li[context="isopen"] {display: none;}',
'.emslides-isopen .emslidecrtr-wrapper .emslidecrtr-controlarea ul li[context="isopen"] {display: inline-block;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel .emslidecrtr-optionarea {display: none; margin-bottom: 2.5em;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel.optionson .emslidecrtr-optionarea {display: block;}',
'.emslidecrtr-wrapper .emslidecrtr-buttonpanel .emslidecrtr-optionarea fieldset {margin: 0.5em;}',
'.emslidecrtr-button {display: inline-block; margin: 0.2em; padding: 3px; min-width: 20px; height: 20px; vertical-align: middle; border-radius: 0.5em; background-color: #ffa; border: 1px solid #333; color: black; font-weight: bold; text-shadow: -1px -1px 1px rgba(0,0,0,0.2), 1px 1px 1px rgba(255,255,255,0.8); box-shadow: -1px -1px 1px rgba(0,0,0,0.3), 1px 1px 1px rgba(255,255,255,0.8);}',
'.emslidecrtr-button svg {width: 20px; height: 20px;}',
'.emslidecrtr-button { text-align: center; ',
'background: rgb(254,252,234); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(254,252,234,1) 0%, rgba(241,218,54,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,1)), color-stop(100%,rgba(241,218,54,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fefcea\', endColorstr=\'#f1da36\',GradientType=0 ); /* IE6-9 */}',
'.emslidecrtr-wrapper .emslidecrtr-button:hover {}',
'.emslidecrtr-listarea h2 {margin: 0.5em 0 0 0; padding: 0 0.2em; font-size: 140%;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist {list-style: none; margin: 0; padding: 0; white-space: nowrap; overflow: auto; height: 14em; font-size: 90%;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li {display: block; border: 1px solid #444; border-radius: 4px; margin: 0.5em; padding: 0; position: relative; box-shadow: -1px -1px 1px rgba(0,0,0,0.4), 1px 1px 1px rgba(255,255,255,0.8), inset 0 3px 8px rgba(255,255,255,0.5), inset 0 -3px 8px rgba(0,0,0,0.5); background-color: #eee;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li a.emslidecrtr-listitem {display: block; min-height: 2em; border-radius: 4px; margin: 0; padding: 0.3em; overflow: hidden; color: black; padding-left: 1em;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li a.emslidecrtr-listitem span.itemcontent {margin-left: 1em;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li a.emslidecrtr-addslide {display: none; height: 20px; width: 20px; border-radius: 50%; border: 1px solid #f0f0f0; margin: -11px auto; padding: 0; text-align: center; color: black; font-weight: bold; background-color: #aaa; }',
'.emslides-editmode .emslidecrtr-listarea ul.emslidecrtr-slidelist li:hover a.emslidecrtr-addslide {display: block;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li a:hover {background-color: rgba(255,170,255,0.5); color: black;}',
'.emslidecrtr-listarea ul.emslidecrtr-slidelist li.currentslide a.emslidecrtr-listitem {background-color: rgba(255,255,170,0.5);}',
'.emslidecrtr-panel {border: 1px solid #777; box-shadow: -1px -1px 1px rgba(0,0,0,0.3), 1px 1px 1px rgba(255,255,255,0.8);}',
'.emslidecrtr-panel {',
'background: rgb(238,238,238); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */",
'background: rgb(214,249,255); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(214,249,255,1) 0%, rgba(158,232,250,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(214,249,255,1)), color-stop(100%,rgba(158,232,250,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* W3C */',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d6f9ff', endColorstr='#9ee8fa',GradientType=0 ); /* IE6-9 */",
'}',
'.emslidecrtr-editpanel {display: none;}',
'.emslides-editmode .emslidecrtr-editpanel {display: block;}',
'.emslidecrtr-editpanel ul.emslidecrtr-editbutlist {list-style: none; margin: 0; padding: 0.2em;}',
'.emslidecrtr-editpanel ul.emslidecrtr-editbutlist li {padding: 0; margin: 0.1em; display: inline-block;}',
'.emslidecrtr-editpanel ul.emslidecrtr-editbutlist li a {}',
'.emslides-editmode .emslidecrtr-wrapper .emslidecrtr-controllist a.emslidecrtr-button-edit {display: none;}',
'.emslidecrtr-wrapper .emslidecrtr-controllist a.emslidecrtr-button-edit {display: inline-block;}',
'.emslidecrtr-wrapper .emslidecrtr-controllist a.emslidecrtr-button-view {display: none;}',
'.emslides-editmode .emslidecrtr-wrapper .emslidecrtr-controllist a.emslidecrtr-button-view {display: inline-block;}',
'.emslides-editmode .editelementtypewikitext:before {content: "Wikitext"; display: block; border: 1px solid red; border-bottom: none; border-radius: 0.2em 0.2em 0 0; background-color: white; color: red; text-shadow: 1px 1px 1px rgba(0,0,0,0.3); padding: 0.1em 0.3em; width: 8em; box-shadow: 2px 2px 2px rgba(0,0,0,0.3); margin-bottom: -1px;}',
'.emslides-editmode .editelementtypetext:before {content: "Text"; display: block; border: 1px solid red; border-bottom: none; border-radius: 0.2em 0.2em 0 0; background-color: white; color: red; text-shadow: 1px 1px 1px rgba(0,0,0,0.3); padding: 0.1em 0.3em; width: 8em; box-shadow: 2px 2px 2px rgba(0,0,0,0.3); margin-bottom: -1px;}',
'.emslides-editmode .emslideelementeditable {border: 1px solid transparent; margin: 0; padding: 20px 0 10px 0; background-color: white;}',
'.emslides-editmode .emslideelementeditable:hover {border: 1px solid black; border-radius: 5px; box-shadow: 0 0 5px rgba(0,0,0,0.5); background-color: #f0f0f0;}',
'.emslides-editmode .emslideelementeditable .mathquill-textbox {background-color: white;}',
'.emslides-editmode ul.emslideelementbuttons {position: absolute; top: -15px; right: 5px; list-style: none; margin: 0; padding: 0; display: none;}',
'.emslides-editmode .emslideelementeditable:hover ul.emslideelementbuttons {display: block;}',
'.emslides-editmode ul.emslideelementbuttons li {display: table-cell;}',
'.emslides-editmode ul.emslideelementbuttons li a.emslidecrtr-button {height: 20px; min-height: 0; min-width: 20px; padding: 1px;}',
'ul.emslidecrtr-addhereelements {list-style: none; margin: -40px 0 -5px 0; padding: 0; height: 10px; display: none; vertical-align: middle;}',
'ul.emslidecrtr-addherepaste {list-style: none; margin: -40px 0 -5px 5px; padding: 0; height: 10px; display: none; vertical-align: middle;}',
'div.emslidecrtr-addherepanel {height: 10px; margin-top: 0; margin-bottom: 10px; border-top: 2px solid #999;}',
'div.emslidecrtr-addherepanel:hover ul.emslidecrtr-addhereelements {display: inline-block;}',
'div.emslidecrtr-addherepanel:hover ul.emslidecrtr-addherepaste {display: inline-block;}',
'div.emslidecrtr-addherepanel ul.emslidecrtr-addhereelements.lastelementpanel {display: inline-block;}',
'div.emslidecrtr-addherepanel ul.emslidecrtr-addherepaste.lastpastepanel {display: inline-block;}',
'div.emslidecrtr-addherepanel:hover {background-color: #eee;}',
'ul.emslidecrtr-addhereelements li {display: inline-block; margin: 0; padding: 0;}',
'ul.emslidecrtr-addhereelements li a.emslidecrtr-button {padding: 1px; min-width: 20px; min-height: 20px; width: auto; height: 20px;}',
'ul.emslidecrtr-addherepaste li {display: inline-block; margin: 0; padding: 0;}',
'ul.emslidecrtr-addherepaste li a.emslidecrtr-button {padding: 1px; min-width: 0; min-height: 0; width: 20px; height: 20px;}',
// Pagecopytools
// Näitä pitää säätää.
'#contentWrapper[pageopen="Slidecreator"].elementselectmode .bookpage [tiddler] {display: block;}',
'#contentWrapper[pageopen="Slidecreator"].elementselectmode .bookpage > [tiddler] > ul.pagecopytools {display: block;}',
'#contentWrapper[pageopen="Slidecreator"].elementselectmode .bookpage > [tiddler]:hover {border-radius: 4px; box-shadow: 0 0 3px rgba(170,0,0,0.8);}',
'#contentWrapper[pageopen="Slidecreator"].elementselectmode .bookpage > [tiddler] > [tiddler]:hover {border-radius: 4px; box-shadow: 0 0 3px rgba(0,0,0,0.5); background-color: #eee;}',
'#contentWrapper[pageopen="Slidecreator"].elementselectmode .bookpage > [tiddler] > [tiddler]:hover > ul.pagecopytools {display: block;}',
// sdeditor specific!
'.emslidecrtr-wrapper .structuredderivation .button.command_qededit,',
'.emslidecrtr-wrapper .emslidecrtr-previewarea [tiddler] [tiddler] .structuredderivation .button.command_qededit {display: none;}',
'.emslides-editmode .emslidecrtr-wrapper .structuredderivation .button.command_qededit {display: inline-block;}',
// Background images
'.emslidecrtr-wrapper {background: transparent url("data:image/png;base64,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") left top repeat;}',
].join('\n')
}
})(jQuery);
//}}}
//{{{
/*********************************************************
* jquery.emathtable.js
* jQuery-plugin for creating a table with math
* Created by: E-Math -project ( http://emath.eu )
* Petri Salmela
* Petri Sallasmaa
* 18.09.2012
* v.1.1
* Copyright: Four Ferries oy
* http://fourferries.fi
* License: GNU AGPL
********************************************************/
(function($){
// jQuery plugin
$.fn.emathtable = function(options){
// Test for numberline commands and trigger command with options.
if (typeof(options) === 'string'){
var cmd = options;
options = arguments[1] || {};
if (typeof(options) === 'string'){
options = {name: options};
}
// Placeholder variable for returning value.
options.result = this;
this.trigger(cmd, options);
return options.result;
}
// Extend default settings with user given options.
var settings = $.extend({
tabletype: 'value_table', // Type of table (styled with css)
theme: "default_theme", // html class for other styling
rows: 2,
cols: 2,
chartVisible: true,
values: [],
editable: false
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
// Create new Emathtable object.
var emtable = new Emathtable(this, settings);
// Init the emathtable
emtable.init();
});
}
var Emathtable = function(place, settings){
// Constructor for Emathtable object.
this.settings = settings;
this.place = $(place);
this.place.addClass('emathtable');
this.theme = this.settings.theme;
this.tabletype = this.settings.tabletype;
this.rows = parseInt(this.settings.rows);
this.cols = parseInt(this.settings.cols);
this.values = this.settings.values;
this.editable = this.settings.editable;
this.chartVisible = this.settings.chartVisible;
this.chartStyle = this.settings.chartStyle;
this.chartParams = this.settings.chart;
if (typeof(this.chartParams) === 'undefined') this.chartParams = new Object();
// Make sure, the table is full rows x cols
for (var i = 0; i < this.rows; i++){
if (this.values.length <= i){
this.values[i] = [];
}
for (var j = 0; j < this.cols; j++){
if (this.values[i].length <= j){
this.values[i][j] = '';
}
}
}
if ($('head style#emathtablestyle').length === 0){
$('head').append('<style id="emathtablestyle" type="text/css">'+Emathtable.strings['style']+'</style>');
}
// Add chart button if chart element has been loaded.
if (typeof($.fn.chart) !== 'undefined') {
if (typeof(this.chartStyle) === 'undefined') this.chartStyle = 'none';
$('<div></div>').chart({showPlot: false});
}
}
Emathtable.prototype.init = function(){
// Init and draw the table
var emathtable = this;
if (this.place.hasClass('emathtable_rendered')){
// return false;
}
this.place.addClass('emathtable_rendered').addClass(this.settings.theme).attr('tabletype',this.tabletype);
var toolbar = this.editable ? '<div class="emtabletoolbar"><a href="javascript:;" class="emtabletoolbutton emtabletypeselect"><span></span></a><a href="javascript:;" class="emtabletoolbutton emtableaddremove"><span></span></a></div>' : '';
var $emtable = $('<div class="emtablewrapper"><table class="emtable"><tbody></tbody></table>'+toolbar+'</div>');
// Add chart button if chart element has been loaded.
if (typeof($.fn.chart) !== 'undefined') {
if ( this.editable ) {
$emtable.find('.emtabletoolbar').append('<a href="javascript:;" class="emtabletoolbutton emtabletogglechart emtablechartglyph pie"><span></span></a>');
}
}
this.emtablenumber = -1;
while ($('#emtable_'+(++this.emtablenumber)).length > 0){};
$emtable.attr('id','#emtable_'+this.emtablenumber)
this.place.empty().append($emtable);
this.table = $emtable.find('table.emtable');
this.tbody = this.table.find('tbody');
this.draw();
this.initEvents();
return this;
}
Emathtable.prototype.draw = function(){
if (this.editable){
this.edit();
} else {
this.show();
}
if ( this.chartVisible ) this.showChart(this.chartStyle);
}
Emathtable.prototype.edit = function(){
var emtable = this;
this.place.addClass('emtable_editmode');
var tablebody = '';
for (var i = 0; i < this.rows; i++){
tablebody += '<tr>';
for (var j = 0; j < this.cols; j++){
tablebody += '<td><span class="mathquill-editable">'+this.values[i][j]+'</span></td>';
}
tablebody += '</tr>';
}
this.tbody.html(tablebody);
this.tbody.find('.mathquill-editable').mathquill('editable').focusout(function(e){
var $elem = $(this);
var $td = $elem.parents('td').eq(0);
var $tr = $td.parents('tr').eq(0);
var $tbody = $tr.parents('tbody').eq(0);
var $alltr = $tbody.find('tr');
var $alltd = $tr.find('td');
var row = $alltr.index($tr);
var col = $alltd.index($td);
emtable.values[row][col] = $elem.mathquill('latex');
emtable.changed();
}).bind('keydown.emtable',function(e){
var $mqelem = $(this);
var instart = $mqelem.children('span').eq(1).hasClass('cursor');
var inend = $mqelem.children('span').last().hasClass('cursor');
var $cell = $(this).parents('td').eq(0);
var $row = $cell.parents('tr').eq(0);
var column = $cell.index();
switch (e.which) {
case 38: // up
if (instart || e.ctrlKey || e.altKey) {
var newcell = $row.prev().find('td').eq(column).find('.mathquill-editable');
$mqelem.focusout();
newcell.focus();
}
break;
case 40: // down
if (inend || e.ctrlKey || e.altKey) {
var newcell = $row.next().find('td').eq(column).find('.mathquill-editable');
$mqelem.focusout();
newcell.focus();
}
break;
case 37: // left
if (e.ctrlKey || e.altKey) {
var newcell = $cell.prev().find('.mathquill-editable');
$mqelem.focusout();
newcell.focus();
}
break;
case 39: // right
if (e.ctrlKey || e.altKey) {
var newcell = $cell.next().find('.mathquill-editable');
$mqelem.focusout();
newcell.focus();
}
break;
case 13: // enter
var newcell = $row.next().find('td').eq(column).find('.mathquill-editable');
$mqelem.focusout();
newcell.focus();
break;
case 27: // esc
$mqelem.focusout();
$mqelem.blur();
break;
default:
break;
}
});
}
Emathtable.prototype.show = function(){
var emtable = this;
this.place.removeClass('emtable_editmode');
var tablebody = '';
for (var i = 0; i < this.rows; i++){
tablebody += '<tr>';
for (var j = 0; j < this.cols; j++){
tablebody += '<td><span class="mathquill-embedded-latex">'+this.values[i][j]+'</span></td>';
}
tablebody += '</tr>';
}
this.tbody.html(tablebody);
this.tbody.find('.mathquill-embedded-latex').mathquill();
}
Emathtable.prototype.allowedChartStyles = function(tabletype) {
if (tabletype === 'none') return(['noborder', 'blank', 'grid_table', 'value_table', 'head_table', 'prop_table']);
if ((tabletype === 'scatter') || (tabletype === 'line') || (tabletype === 'spline')) return(['noborder', 'blank', 'grid_table', 'value_table']);
if ((tabletype === 'bar') || (tabletype === 'pie')) return(['noborder', 'blank', 'grid_table', 'head_table', 'prop_table']);
return([/* Unkown table type has no chart affiliations. */])
}
Emathtable.prototype.initEvents = function(){
var emtable = this;
this.place.bind('get', function(e, options){
return emtable.getData(options);
});
this.place.bind('tabletype', function(e, options){
return emtable.setType(options);
});
this.place.find('a.emtabletypeselect').click(function(e){
if ($(this).hasClass('isopen')){
$(this).parent('.emtabletoolbar').find('.emtabletypelistwrapper ul')
.hide('slide', {direction: 'left'}, 300, function(e){
$(this).parents('.emtabletypelistwrapper').remove()
});
$(this).removeClass('isopen');
} else {
// Close the other menus if open.
var chartSelect = $(this).parents('.emathtable').find('a.emtabletogglechart');
if ( chartSelect.hasClass('isopen') ) chartSelect.click();
$(this).parent('.emtabletoolbar')
.append(
'<div class="emtabletypelistwrapper">\
<ul>\
<li><a href="javascript:;" ttype="noborder"><span></span></a> No border</li>\
<li><a href="javascript:;" ttype="blank"><span></span></a> Blank</li>\
<li><a href="javascript:;" ttype="grid_table"><span></span></a> Grid table</li>\
<li><a href="javascript:;" ttype="value_table"><span></span></a> Value table</li>\
<li><a href="javascript:;" ttype="head_table"><span></span></a> Categorized</li>\
<li><a href="javascript:;" ttype="prop_table"><span></span></a> Counts</li>\
</ul>\
</div>')
.find('.emtabletypelistwrapper ul')
.hide().show('slide',{direction: 'left'}, 300)
.find('a').click(function(e){
$(this).parents('.emathtable').emathtable('tabletype', $(this).attr('ttype'));
if (emtable.allowedChartStyles(emtable.chartStyle).indexOf(emtable.tabletype) < 0) emtable.hideChart();
emtable.changed();
});
$(this).addClass('isopen');
}
});
this.place.find('a.emtabletogglechart').click(function(e){
if ($(this).hasClass('isopen')){
$(this).parent('.emtabletoolbar').find('.emtablechartlistwrapper ul')
.hide('slide', {direction: 'left'}, 300, function(e){
$(this).parents('.emtablechartlistwrapper').remove()
});
$(this).removeClass('isopen');
} else {
// Close the other menus if open.
var typeSelect = $(this).parents('.emathtable').find('a.emtabletypeselect');
if ( typeSelect.hasClass('isopen') ) typeSelect.click();
var chartMenu =
'<div class="emtablechartlistwrapper">\
<ul>'
if (emtable.allowedChartStyles('none').indexOf(emtable.tabletype) >= 0) chartMenu += '<li><a href="javascript:;" ctype="none" ' + (emtable.chartStyle == 'none' ? 'class="selected"': '') + '><span></span></a> None</li>';
if (emtable.allowedChartStyles('scatter').indexOf(emtable.tabletype) >= 0) chartMenu +='<li><a href="javascript:;" ctype="scatter" ' + (emtable.chartStyle == 'scatter' ? 'class="selected"': '') + '><span></span></a> Scatter plot</li>'
if (emtable.allowedChartStyles('line').indexOf(emtable.tabletype) >= 0) chartMenu +='<li><a href="javascript:;" ctype="line" ' + (emtable.chartStyle == 'line' ? 'class="selected"': '') + '><span></span></a> Line plot</li>'
if (emtable.allowedChartStyles('spline').indexOf(emtable.tabletype) >= 0) chartMenu +='<li><a href="javascript:;" ctype="spline" ' + (emtable.chartStyle == 'spline' ? 'class="selected"': '') + '><span></span></a> Spline plot</li>'
if (emtable.allowedChartStyles('bar').indexOf(emtable.tabletype) >= 0) chartMenu +='<li><a href="javascript:;" ctype="bar" ' + (emtable.chartStyle == 'bar' ? 'class="selected"': '') + '><span></span></a> Bar chart</li>'
if (emtable.allowedChartStyles('pie').indexOf(emtable.tabletype) >= 0) chartMenu +='<li><a href="javascript:;" ctype="pie" ' + (emtable.chartStyle == 'pie' ? 'class="selected"': '') + '><span></span></a> Pie chart</li>'
chartMenu += '</ul>\
</div>'
$(this).parent('.emtabletoolbar')
.append(chartMenu)
.find('.emtablechartlistwrapper ul')
.hide().show('slide',{direction: 'left'}, 300)
.find('a').click(function(e){
$(this).parents('.emtablechartlistwrapper ul').find('li a').removeClass('selected');
$(this).addClass('selected');
emtable.showChart($(this).attr('ctype'));
emtable.changed();
});
$(this).addClass('isopen');
}
});
this.place.find('a.emtableaddremove').click(function(e){
if ($(this).hasClass('isopen')){
emtable.hideAddremove();
$(this).removeClass('isopen');
} else {
emtable.showAddremove();
$(this).addClass('isopen');
}
});
return this;
}
Emathtable.prototype.getData = function(options){
var data = {rows: this.rows, cols: this.cols, values: this.values, tabletype: this.tabletype, theme: this.theme};
if (typeof($.fn.chart) !== 'undefined') {
data.chartVisible = this.chartVisible;
data.chartStyle = this.chartStyle;
data.chartParams = this.chartParams;
}
options.result = data;
}
Emathtable.prototype.setType = function(options){
this.tabletype = options.name;
this.place.attr('tabletype',this.tabletype);
}
Emathtable.prototype.showChart = function(chartStyle) {
if ( typeof(chartStyle !== 'undefined') ) this.chartStyle = chartStyle;
if (typeof($.fn.chart) !== 'undefined') {
if ( this.chartStyle === 'none' ) this.hideChart();
else {
var chart = this.place.find('.chart').empty();
if (chart.length == 0) this.place.append('<div class="chart"></div>');
var opt = {}; this.getData(opt);
opt.result.chartStyle = this.chartStyle;
opt.result.showPlot = true;
opt.result.dataMode = 'normal';
opt.result.rowLabels = 'auto';
opt.result.colLabels = 'auto';
if (this.tabletype == 'prop_table') {
opt.result.dataMode = 'counts';
opt.result.rowLabels = true;
opt.result.colLabels = true;
}
else if ((this.tabletype == 'value_table') || (this.tabletype == 'head_table')) {
opt.result.colLabels = true;
}
opt.result = $.extend(this.chartParams, opt.result);
this.place.find('.chart').chart(opt.result);
}
}
}
Emathtable.prototype.hideChart = function() {
if (typeof($.fn.chart) !== 'undefined') {
this.chartStyle = 'none';
this.place.find('.chart').remove();
}
}
Emathtable.prototype.showAddremove = function(){
var emtable = this;
this.table.addClass('emtable_addremove');
var removetr = '<thead class="emtableremovetr"><tr>';
var addtr = '<thead class="emtableaddtr"><tr>';
for (var i = 0; i < this.cols; i++){
removetr += '<td><a href="javascript:;" class="emtableremovecol"><span></span></a></td>';
addtr += '<td><a href="javascript:;" class="emtableaddcol"><span></span></a></td>';
}
removetr += '</tr></thead>';
addtr += '<td><a href="javascript:;" class="emtableaddcol"><span></span></a></td></tr></thead>'
this.tbody
.before(removetr)
.after(addtr);
this.tbody.find('tr td:first-child').prepend('<a href="javascript:;" class="emtableremoverow"><span></span></a>');
this.tbody.find('tr td:last-child').prepend('<a href="javascript:;" class="emtableaddrow"><span></span></a>');
this.table.find('thead.emtableaddtr td:last-child').prev().prepend('<a href="javascript:;" class="emtableaddrow"><span></span></a>');
// Add row
this.table.find('a.emtableaddrow').click(function(e){
var $alink = $(this);
var $parent = $alink.parents('tbody, thead');
var $tr = $alink.parents('tr').eq(0);
var row;
if ($parent[0].tagName === 'TBODY'){
row = $parent.find('tr').index($tr);
} else {
row = emtable.rows;
}
var newrow = [];
for (var i = 0; i < emtable.cols; i++){
newrow.push('');
}
emtable.values.splice(row, 0, newrow);
emtable.rows += 1;
emtable.init();
emtable.place.find('a.emtableaddremove').click();
emtable.changed();
});
// Remove row
this.table.find('a.emtableremoverow').click(function(e){
var $alink = $(this);
var $parent = $alink.parents('tbody');
var $tr = $alink.parents('tr').eq(0);
var row = $parent.find('tr').index($tr);
emtable.values.splice(row, 1);
emtable.rows -= 1;
emtable.init();
emtable.place.find('a.emtableaddremove').click();
emtable.changed();
});
// Add column
this.table.find('a.emtableaddcol').click(function(e){
var $alink = $(this);
var $parent = $alink.parents('thead');
var $td = $alink.parents('td').eq(0);
var $alltd = $alink.parents('tr').eq(0).find('td');
var col = $alltd.index($td);
for (var i = 0; i < emtable.rows; i++){
emtable.values[i].splice(col, 0, '');
}
emtable.cols += 1;
emtable.init();
emtable.place.find('a.emtableaddremove').click();
emtable.changed();
});
// Remove column
this.table.find('a.emtableremovecol').click(function(e){
var $alink = $(this);
var $parent = $alink.parents('thead');
var $td = $alink.parents('td').eq(0);
var $alltd = $alink.parents('tr').eq(0).find('td');
var col = $alltd.index($td);
for (var i = 0; i < emtable.rows; i++){
emtable.values[i].splice(col, 1);
}
emtable.cols -= 1;
emtable.init();
emtable.place.find('a.emtableaddremove').click();
emtable.changed();
});
}
Emathtable.prototype.hideAddremove = function(){
this.table.removeClass('emtable_addremove');
this.table.find('.emtableremovetr').remove();
this.tbody.find('a.emtableremoverow').remove();
this.table.find('.emtableaddtr').remove();
this.tbody.find('a.emtableaddrow').remove();
}
Emathtable.prototype.changed = function(){
if (typeof($.fn.chart) !== 'undefined') {
var chart = this.place.find('.chart').empty();
if (chart.length > 0) {
var opt = {}; this.getData(opt);
opt.result.chartStyle = this.chartStyle;
opt.result.showPlot = true;
opt.result.dataMode = 'normal';
opt.result.rowLabels = 'auto';
opt.result.colLabels = 'auto';
if (this.tabletype == 'prop_table') {
opt.result.dataMode = 'counts';
opt.result.rowLabels = true;
opt.result.colLabels = true;
}
else if ((this.tabletype == 'value_table') || (this.tabletype == 'head_table')) {
opt.result.colLabels = true;
}
opt.result = $.extend(this.chartParams, opt.result);
chart.chart(opt.result);
}
}
var e = jQuery.Event("emathtable_changed");
this.place.trigger( e );
}
Emathtable.strings = {
style: '.emtablewrapper, .emathtable a.emtabletoolbutton {display: inline-block; padding: 0.3em; border: 1px solid #777;'+
'background: rgb(255,255,255); /* Old browsers */'+
'background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%); /* FF3.6+ */'+
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1))); /* Chrome,Safari4+ */'+
'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Chrome10+,Safari5.1+ */'+
'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Opera 11.10+ */'+
'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* IE10+ */'+
'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* W3C */'+
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffff\', endColorstr=\'#e5e5e5\',GradientType=0 ); /* IE6-9 */}'+
'.emtable_editmode .emtablewrapper {min-height: 150px;}'+
'.emathtable a.emtabletoolbutton {padding: 2px; margin: 3px 0; border-radius: 3px; height: 20px; width: 20px; display: block;}'+
'.emathtable a.emtabletoolbutton span { height: 20px; width: 20px; display: inline-block; margin: 0; padding: 0;}'+
'.emathtable a.emtabletoolbutton.emtabletypeselect span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADaAAAA2gBkEje+AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQoSURBVDiNhVRdSFtnGH6+es5pmkwdDCEJawmrtHbpZMKkmVWzYVAbbxyGYSgUGatzEJi0K5SWliIRd9HrDYfbGOvNhnQMJk6oImQXk9LOn2lrdaVWG/+Sk+SYmZNzvnPe3XjE1K774L34eN/v4Xne93k/RkR42fF6vZ+HQqHPANDg4OBXs7OzfS+rF16KBuDo0aPV4XD49YMHD+L+/fvevTnGGKPnGB3Ye/H7/d80NDT8whgr3nlgc7vdHkmSIIoinE6nhzEmAYDL5fJ0dHT83tTUNFDAgIhARKipqekfHh7OT0xMUGdn59zp06d/uHLlysK9e/eMlZUV2tjYoAcPHvDe3t75YDD408DAwHImk6Gpqal8IBD42sLZlayq6hJjjImiiAsXLpwQRfGEIAgQRRGSJEGSJHg8nqLu7u5j3d3dx3RdB+cc2WyWJ5PJmX0MiQihUGj04cOHtLi4SE+fPqW1tTWSZZmy2SzlcjnKZrOkKAqlUilKJBK0vLxMZ86cGdyLUdDDzc3Nx4IgwGaz7YbdbkcymSRZlgEAnPOCSKVSmy+cMmPMdv369fccDseuzK2tLd7T0zMzNjb2vSAIr9TX13/Q1dX1dnFxcZFhGCgqKkJjY2MjY6yYiLYAgFVVVfVUVFS8WVZWdrirq+sdp9N5wJrqjRs3pvr6+qosazDG2KVLl6YvXrx4MpfLQdM0KIqCsbGx1Xg8vjk5OTkrtLe3d5w7d+6wKIq7zIgI2WwWo6Ojv+31GRGRz+f7tbOz86Su69A0zXKIi3PuOnToUIkgy7Jo9U0QBBiGAcMwwBiDKIqvPm90xliJaZpQVRX5fB6maYJzjmfPntH8/Lwg3Lp16+NYLPa+2+1+KxqNBlwu1wELsKWlJcAYcxDRPztgjmvXrjVpmgZL8vr6un758uXvFEX5WZblaWFlZWUIwBBjTKysrJyJRCLHOecwTRPhcPgNSZL+qq+vHzdNE9Fo1N/c3OxJp9PI5/MwDAOxWOzxkydPPiUis2DKRKQHAoHR8+fPHwdgyWZtbW2e1tbWDs45tre3oSgKNE2Dpmmw2WyYnp7+2wIr2GXGGHM4HF7DMMA5hyVLURSkUikkEgmk02moqopcLgfTNKHrOoLBYLXL5areB+jz+b64evVqjVWoquouaC6Xg6qqUFUVuq5DkiQYhmGKooja2tqyurq6fsaYUCDZbreXAUAikTBv3rz558LCwvSpU6febWhoKC8pKRF2WNHIyMhiLBYbMU1TPnv27CeVlZWvxePxGSLi+3bZ7/d/W1tb+yUAYcd+Qnl5+Y937tyhoaEhikQicwDsVr3T6az2er39ANi+3wYAxsfHP9p7JyLu8XhGMpnMh6WlpZBlOU5E21Z+dXX1LoC7L9zl/zpLS0t/3L59O37kyBHj0aNHc/9X/y9quGeGFrS2jQAAAABJRU5ErkJggg==") center center no-repeat;}'+
'.emathtable a.emtabletoolbutton.emtableaddremove span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADHQAAAx0Bme/POQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFjSURBVDiNzZO/SwJhGMe/793pC915VGIFQdAUqOfUUmNgIP34F3Jta6yhWoS2psYGh/YQciqSwL8gCHRoEJq80tLzTe/X23QSqHSHFn2nh+cLH54vz/MQzjkmKWGiNADSQIcQcptOn0mh0HKHsdPtUqkyFjCfSMxr0egBpZSiXq8COAkCHBWZAAAnhASBAQDxlnKXyZxTSlfAuaCq6qYoikK73X60HefFdV3zo9E43C2Xqz8B+5EVWd5TFGX2uxmJRFIAUgBgmeYDAP9Ag7GCw3mcuy5RFWVVEEXBMIxnh/NX17Z7jLH7QJE95ZPJBU3TapTScF3XcxvF4rEfkKffv0M5HtffW61LSRSXuowVggIHIo+rP3i9IVrfv1mUlXBW4Bh66J1u77p8sfPkGzgzPZWLxeayo/xGs7EGYMs30LRd3bKskb5l2m9e7W/CWvOoUtevuCsMjdyUPvsf9P+3PHHgFyEbhXpQOuT5AAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable a.emtabletoolbutton.isopen {border-color: red; background: rgb(229,229,229); /* Old browsers */'+
'background: -moz-linear-gradient(top, rgba(229,229,229,1) 0%, rgba(255,255,255,1) 100%); /* FF3.6+ */'+
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(229,229,229,1)), color-stop(100%,rgba(255,255,255,1))); /* Chrome,Safari4+ */'+
'background: -webkit-linear-gradient(top, rgba(229,229,229,1) 0%,rgba(255,255,255,1) 100%); /* Chrome10+,Safari5.1+ */'+
'background: -o-linear-gradient(top, rgba(229,229,229,1) 0%,rgba(255,255,255,1) 100%); /* Opera 11.10+ */'+
'background: -ms-linear-gradient(top, rgba(229,229,229,1) 0%,rgba(255,255,255,1) 100%); /* IE10+ */'+
'background: linear-gradient(to bottom, rgba(229,229,229,1) 0%,rgba(255,255,255,1) 100%); /* W3C */'+
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#e5e5e5", endColorstr="#ffffff",GradientType=0 ); /* IE6-9 */}'+
'.emtabletoolbar {display: inline-block; margin-left: 0.5em; vertical-align: top; position: relative;}'+
'.emtabletoolbar .emtabletypelistwrapper {position: absolute; right: -0.35em; top: -0.3em;}'+
'.emtabletoolbar .emtabletypelistwrapper ul {position: absolute; left: 0; top: 0; padding: 0; margin: 0; list-style: none; border: 1px solid #777; border-left: none; border-radius: 0 0.3em 0.3em 0; overflow: hidden;}'+
'.emtabletoolbar .emtabletypelistwrapper ul li {font-size: 80%; margin: 0; padding: 0; padding-right: 10px;'+
'background: rgb(255,255,255); /* Old browsers */'+
'background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%); /* FF3.6+ */'+
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1))); /* Chrome,Safari4+ */'+
'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Chrome10+,Safari5.1+ */'+
'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Opera 11.10+ */'+
'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* IE10+ */'+
'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* W3C */'+
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffff\', endColorstr=\'#e5e5e5\',GradientType=0 ); /* IE6-9 */}'+
'.emtabletoolbar .emtabletypelistwrapper ul li a {vertical-align: middle; margin: 0; padding: 0.2em; display: inline-block; width: 20px; height: 20px; margin-right: 5px;}'+
'.emathtable {text-align: center;}'+
'.emathtable .emtablewrapper {text-align: left; white-space: nowrap;}'+
'.emathtable a.emtabletoolbutton {color: black; text-shadow: 1px 1px 1px white;}'+
'.emathtable a.emtabletoolbutton:hover {color: black; text-shadow: 2px 2px 1px white;}'+
'.emathtable .emtablewrapper .mathquill-editable {display: block; background-color: white; border: 1px dotted #ccc;}'+
'.emathtable table.emtable {display: inline-block; margin: 10px;}'+
'.emathtable[tabletype="default"] table.emtable { border-collapse: collapse;}'+
'.emathtable[tabletype="default"] table.emtable tbody tr:first-child td {border-bottom: 1px solid black;}'+
'.emathtable[tabletype="default"] table.emtable tbody td {border-left: 1px solid black; padding: 0.2em;}'+
'.emathtable[tabletype="default"] table.emtable tbody td:first-child {border-left: none;}'+
'.emathtable[tabletype="value_table"] table.emtable {border-collapse: collapse; background-color: white;}'+
'.emathtable[tabletype="value_table"] table.emtable tbody tr:first-child td {border-bottom: 2px solid black; text-align: center;}'+
'.emathtable[tabletype="value_table"] table.emtable tbody td {border-left: 2px solid black; padding: 0.2em; min-width: 2em; text-align: right;}'+
'.emathtable[tabletype="value_table"] table.emtable thead td {padding: 0 0.2em;}'+
'.emathtable[tabletype="value_table"] table.emtable tbody td:first-child {border-left: none;}'+
'.emathtable[tabletype="grid_table"] table.emtable {border-collapse: collapse;}'+
'.emathtable[tabletype="grid_table"] table.emtable tbody td {border: 1px solid black; padding: 0.2em; background-color: white; min-width: 3em;}'+
'.emathtable[tabletype="grid_table"] table.emtable thead td {padding: 0 0.2em;}'+
'.emathtable[tabletype="noborder"] table.emtable {border-collapse: collapse;}'+
'.emathtable[tabletype="noborder"] table.emtable tbody td {border: none; padding: 0.2em; min-width: 3em;}'+
'.emathtable[tabletype="blank"] table.emtable {border-collapse: collapse; background-color: white;}'+
'.emathtable[tabletype="blank"] table.emtable tbody td {border: none; padding: 0.2em; min-width: 3em;}'+
'.emathtable[tabletype="blank"] table.emtable thead td {padding: 0 0.2em;}'+
'.emathtable[tabletype="head_table"] table.emtable {border-collapse: collapse; background-color: white;}'+
'.emathtable[tabletype="head_table"] table.emtable tbody {background-color: white;}'+
'.emathtable[tabletype="head_table"] table.emtable tbody tr:first-child td {border-bottom: 2px solid black; text-shadow: 1px 0 0 black;}'+
'.emathtable[tabletype="head_table"] table.emtable tbody td {border: none; padding: 0.2em 0.5em; min-width: 3em;}'+
'.emathtable[tabletype="head_table"] table.emtable thead td {padding: 0 0.5em;}'+
'.emathtable[tabletype="prop_table"] table.emtable {border-collapse: collapse;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody {background-color: white;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr:first-child td {border: 2px solid black; text-shadow: 1px 0 0 black; text-align: center;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr td:first-child {border: 2px solid black; text-shadow: 1px 0 0 black; min-width: 1.5em; text-align: center;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody td {border: 2px solid #aaa; padding: 0.2em 0.5em; min-width: 2em;}'+
'.emathtable[tabletype="prop_table"] table.emtable thead td {padding: 0 0.5em;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr:last-child td {border-bottom: 2px solid black;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr td:last-child {border-right: 2px solid black;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr:first-child td:first-child {background-color: black;}'+
'.emathtable[tabletype="prop_table"] table.emtable tbody tr:first-child td:first-child .mathquill-editable, .emathtable[tabletype="prop_table"] table.emtable tbody tr:first-child td:first-child .mathquill-embedded-latex {visibility: hidden;}'+
'.emathtable .emtabletypelistwrapper a[ttype] span {display: inline-block; width: 20px; height: 20px; padding: 0; margin: 0;}'+
'.emathtable a[ttype="noborder"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEvSURBVDiNzVUxjsIwEBwv4BR0pCQlokVKxYPyj5B/8KCrIqWhiK6E0hSEKPIG1tec0RUmAnFITGV5xuP1WF4r5xyKolhorbcislJKjfAEnHNXIqqYOcvz/FttNptFFEVfaZrO4jhWz5h5GGNcWZZHa+2atNbbV8wAII5jlabpTGu9JRFZvWL211REVmOfGREhiqKguO97AMBkMgny1lqICJRSo7GfnE6nWC6XwQX7/R4AkCRJkK/rGk3TAADoofM8gc83vGXIzDgcDkHR+XwGgLs8M9/G76tQa435fB4U+Vu+x7dtC2vteyr8fMNbhm3bYrfbBUX+6Z1OpyDv8wOAsXPuCgAigq7rBne/XC6D/G9vpMoY4waVD8AY44ioImbOyrI8vmLqGywzZ+q/v4AfEOqj8NZHkMAAAAAASUVORK5CYII=") center center no-repeat;}'+
'.emathtable a[ttype="blank"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEZSURBVDiNzVUxisMwEJyVjZK4MnGXOr1B1T0o/4j9Dz/oKkH6g3TplCrEWMi7V8kcQYEYXyBTCa00u5qRViQiaNt2r7XumLkmogwzICKjUurkvT8cj8cfappmv1qtvo0x26qqaA5ZhHNOrLXXYRi+lNa6W0IGAFVVkTFmq7XuFDPXS8j+kjJznUfNdrsd1ut1crGIAACI0nmZGefzGUSU5XFys9mgLMvkhvv9DgAoiiIZv91uU1L10nlm4PMJJw3HcZy0ekQIAQCexpl5Gr+vwizLnrr4issRn2/K+zTs+3667Y+ILg7DkIyHEKZnmYvICACXy2VRZUQUe6M6OefSpc2Ac06UUiflvT9Ya69LSGOD9d4f6L+/gF+FRZwQUAoffgAAAABJRU5ErkJggg==") center center no-repeat;}'+
'.emathtable a[ttype="value_table"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFDSURBVDiN7VWxbsIwED2fIyMxJsrAxsCOlCyd+jUM/EWShW9gYMh/sFSdEBIR3TuwZTLKFCVW7OvSuJhmIWLkSTe8d/bz6aQ7MyKCLMsWQoidMWbJGOPwAIhII+KXUmqVJMk3S9N0MZlMDlEU+UEQsEfMekgpqSiKa9u2byiE2PVmxhgYE0EQsCiKfCHEzjPGLPvKfN+H2WxmX95ut7Ber51q7rWyLKGqKvgtaOnd9oxzDtPp1B5GRIcPaZz/tZwxxr3bw1praJrG8q7rHD6kaa2dvGN4Pp9hv99bfjweIc9z58K9FoYhzOfzYcM4jp1k0zT/enivXS4XkFJajvBkvAxfhiPgEZGdHa011HVtk0ophw9pt6NHRJptNpuPOI7f+/U1BogIUko6nU6fqJRaFUVxlVISIsKY6BesUmrFnv0F/ACrpuO/ULqQBQAAAABJRU5ErkJggg==") center center no-repeat;}'+
'.emathtable a[ttype="grid_table"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGsSURBVDiN7VW7igIxFL2ZHUZ8gThON83A9kK0sNrGxtKP8AP8A7XQ2g+w8EeEcatBzMB2AVd8IIxIxm4GDJhsZdgsLIu42+2FQM65Jye5l5AgKSUMBoNny7ImQogqQugJ7ggp5dUwjDfOeafX672jfr//nMlkAoxx2bZtdI/ZLeI4lmEYni+XS8O0LGtyMzscDpCm6V1muVwOXNdFGOMyIWRiCCGqt5P5vg+e56lBKQXHcTSOEKJh3/cBAMC2bSSEqJqfe1apVKDRaKjdKaVQr9ehVCopLggCTTObzdQcIfRk3NmuH8P8DDabDYzHY4UXiwVEUQTZbFZx8/kcvq751tDzPOh2uwpPp1Not9tayQCgaYbDoZb725KTJAFKqcJRFMFqtYJisai40+mkaZIk+d4wTVPYbrcKM8Zgv99DPp9X3Pl81jRf761m6DgOtFothY/HIzSbTa2HlFJNQwjRDP+vzeNhSimvN8AYgyAIVHK9XsNyuYRCoaC43W6naRhjai6lvKLRaOTXarWXB58viONYEkJeTc55JwzDAGNcdl33oQeWc95Bv/0FfACxFPVr51SxMAAAAABJRU5ErkJggg==") center center no-repeat;}'+
'.emathtable a[ttype="head_table"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHASURBVDiNrZWxiupAGIXPTOIIlgkpIhEsFgUthIhwC7lP43uo7+GbaKfFBSFop7KFhWAhE2yUZHRmbnE3Gtmwmr17YJqTyZeT/zAJ0VpjOBy+McZGSqkWIcRADmmtJaV0KYTo9fv9dzIYDN6KxeIf3/ct27ZJHlgizrkOgiCM4/gXZYyNEphSCt9Ztm0T3/ctxtjIVEq1kmSWZcF13Vzp9vs9jscjPgK1zPTMDMNAqVRCp9PB4XAAAHieh9lsBgDodrvY7XYAAMdxMJ/PYRj3kRNCDDP9NCkloijCdDp9SBFFEQBgMpl88qWUD94DcLFYYDwe53plx3FQrVazge12++HiK9put+CcZwMTrddrXC4XAABjDLVaDQCw2WwghAAAFAoF1Ov1T/dmAiuVCpRSAABK6c33PC/Tfwo8nU63YSfNf+U/BabbM837ljiOcb1eb8CXE5bLZWitAQCE3E+j67qZ/lPgarV6KKXRaAD4V1a6lGaz+RowayOAG/grZVf1HzK11rezI6XE+XzOBUgfPa21NCmlS875b9u2SRiGCMMwdypKKTjnmlK6pEKIXhAE4YeB76zkAyuE6JGf/gX8BeftCu0bneKdAAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable a[ttype="prop_table"] span {background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHkSURBVDiNvZWxquJAFIb/GWMEsdGYLs3A7YUUYrWk9EF8AN9ALW6fB/BVhNjZJGiXYiEKNoLRgDExCWZucZnB7HpZZO/uX53JOfNx5sw5E8I5x2w2e1NVdV6WZY8QUsML4pzfKaWbPM9Hk8nkJ5lOp2+NRmNlmmZH0zTyCkwoDEPued4py7KBoqrqXMD2+z2SJHkJ1mw2YRgGMU2z47runJZl2ROZOY4DxhgYY3BdV9ppmiJN06c+x3EAAJqmkbIse8pjzbrdLgaDAQBgtVpJW+iZb7FYSD8hpEZfrdefpDwugiCAbdsAgOVyKb+fTieZGQC4rivjgiD4GsgYw3g8lmthn89nAEC73ZYQxhgA4P39vQL8t0e+Xq/wfR8AEEUR4jgGAKRpCgCo1+sAgCzLpE9RKogqMEkSbLdbAMDlcpGg2+1WARZFIX21WnWwKkBd1zEcDgEAvu9D1/VKFqKGcRxLX5ZlFeD/a5v1ei1bQoxjFEUAgDAM5Z5Wq/U18LFtbNuWrfFr24hYAPJyhL7/yJzzu1gcj0c5DbvdTtr3+2eIuNGiKHA4HOQeIc75XaGUbsIw/KFpGrEsS9at3+//NlbPZFkWgM83kVK6UfI8H3metzJNs2MYxl89sHmej8h3/wI+AMNJDG43soGGAAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable table.emtable_addremove {margin: 10px;}'+
'.emathtable thead.emtableremovetr tr:first-child td {border: none; text-shadow: none; font-weight: bold; text-align: center;}'+
'.emathtable tbody tr td:first-child a.emtableremoverow {display: block; font-weight: bold; text-align: center; position: relative;}'+
'.emathtable tbody tr td:first-child a.emtableremoverow span {display: inline-block; position: absolute; width: 10px; left: -15px; top: 5px;}'+
'.emathtable a.emtableremoverow, .emathtable a.emtableremovecol {'+
' display: block; position: relative; height: 0;}'+
'.emathtable a.emtableremoverow:hover, .emathtable a.emtableremovecol:hover {'+
'}'+
'.emathtable a.emtableremoverow span, .emathtable a.emtableremovecol span {display: inline-block; width: 10px; height: 10px; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC+SURBVBiVfZBNCoJgFEWv8VIyokEEGUFIK2hU6wjciAtxC62kkdtwGAlFZH/W59P3GtTwyzs+3MO9Tpqmke/7seu6ASypqiovyzIhz/PiMAzXNuiXeZZlMRFRwMwtHEBEAakqLrc39qfSCs3GPlQVVNc1trsjDnfXCk4HD2yWgo6qQlT+akXl29g0DaLVEIezsTeO+uDXFSQi6HUVi4ldDSjMU0DMnDPzvG01M+dkjEmKoogdx7Eerqq5MSb5AHBcXly73qJbAAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable a.emtableremovecol span {position: absolute; top: -7px;}'+
'.emathtable thead.emtableaddtr tr:first-child td {border: none; text-shadow: none; font-weight: bold; text-align: left;}'+
'.emathtable thead.emtableaddtr tr:first-child td a.emtableaddcol {display: block; height: 0; position: relative;}'+
'.emathtable thead.emtableaddtr tr:first-child td a.emtableaddcol span {position: absolute; left: -10px; top: -10px;}'+
'.emathtable tr td a.emtableaddrow {display: block; font-weight: bold; height: 0; text-align: center; position: relative;}'+
'.emathtable tr td a.emtableaddrow span {display: inline-block; position: absolute; width: 30px; right: -28px; top: -10px;}'+
'.emathtable thead tr td a.emtableaddrow span {right: -28px;}'+
'.emathtable a.emtableaddrow span, .emathtable a.emtableaddcol span {'+
' display: inline-block; width: 10px; height: 10px;}'+
'.emathtable a.emtableaddcol span {height: 30px; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAdCAYAAACT4f2eAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHGSURBVDiNpZG/a1NRGIaf7+Sa5Fx7ETsFCk3o0KV31TX0T5AqQgvaf6Czzt0cXFw7mU2w4CKFbCFTx2JLbYaSDqKTNyX2QnLPD4dcS8hNNeC7nMNzXt7vO98n3num1YrjlwAvTk/fT3PFjJxSm06pzVkezALx/nqW5dzP4wUVSrfieL8Vx/v/LO2UWp2XOK/HLwsZR5XKu4WM5fH4IL/uTvPCZ+5SIRH4tKjx66LG1/m5Ow3/q8e384yFRPF+VbwvbKeQ6EWe5dfPf028S+K9l06n87RUKjUBXJoGACoMDYC1ttNsNj9Kt9ttNRqN51EUlQGuz84AeLCxAcBwOBz3+/0PQRiGj7TWZWMMN1dX/DzIV723x/16Ha11WWv9WImINsZgjGE0GKCsRVnLaDDgD1dKVQNrLcnJCaPLS8ZJQlUEgMHxMWmvR2VtDbu8TOCc49fREdUkQQPkRn1xMenx/By/s4NyzmGXlkhFSKfGkQKpCDaKcM5NEh9ub08eez3c4SEApa0twvV1AJIkmRiNMeQz416eaK295c45gizLvhlj6gClWo2blRUAyrXarTHLsu/SbrefiMirIAhq81ZnjPnhvX/zG0Gnw/phbkEiAAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable a.emtableaddrow span {width: 30px; background: transparent url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAKCAYAAABIQFUsAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGQSURBVDiNrZS9ThtBFIW/mf0Z2ZLXsuSClQBLFK6gTpNIpEnpR0iPeAK/AJUL0lCblipNJMuSq8RFekCCrVD4CShWZAsGe3d2boqgVCjV3vKe4tO59+goEaGqmU6nR41GY1drXX9Nz/P8xlo7UFVBR6PR2263+6XVaiUAj5eX/Do5gWaTzv4+SmsAsiz7HlZCBIwx72q1WlIUBQCPWUY0m7Gczcifn9FxDEAURWuVQQGcc9jra4rFAnt/j3nZ/z47Q4Uh9U4HEUENt7f3RKk32vu7j6en/eOdnU+iVFN7/y0qis8rYwYA2vtjJWLLINgDCJ3ruzB8D3xQInb98PDHWhwf5MMhQVGglEIpBYD3HoDV5ibS613pKp165+A/GRHv/zqtKkiTyaSfpulB8fBAOZ+zOj+ncXGBFUH3eugwxGxsMF8uryr7aVmWOOcI2m2Cdht3e/tPi7e20FGEAN5aKoN6779aaxfGmASANOUpSXD1OpEI5Uuq8zz/Wdl5Acbj8VEcx7vAq+Xgvb8py3LwB05BuvDbIBg7AAAAAElFTkSuQmCC") center center no-repeat;}'+
'.emathtable a.emtableaddrow span:hover, .emathtable a.emtableaddcol span:hover {'+
'}' +
'.emathtable[tabletype="value_table"] a[ttype="value_table"], .emathtable[tabletype="grid_table"] a[ttype="grid_table"], .emathtable[tabletype="blank"] a[ttype="blank"], .emathtable[tabletype="noborder"] a[ttype="noborder"], .emathtable[tabletype="head_table"] a[ttype="head_table"], .emathtable[tabletype="prop_table"] a[ttype="prop_table"] {border: 1px solid red;}'+
''
}
})(jQuery)
// TiddlyWiki-macro for usage of tables in TiddlyWiki
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.emathtable = {
/******************************
* Show emathtable
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('Missing table.', place, null, tiddler);
return false;
}
var tableid = params[0];
var iseditable = (params[1] === 'edit'|| params[1] === 'authordialog');
var emtabletext = '{{emathtable emathtable_'+tableid+'{\n}}}';
wikify(emtabletext, place);
if (tiddler) {
var settings = jQuery.extend(true, {}, tiddler.data('emathtable',{}));
} else {
var settings = {};
}
settings[tableid] = settings[tableid] || {};
settings[tableid].editable = iseditable;
var emtable = jQuery(place).find('.emathtable.emathtable_'+tableid).last().emathtable(settings[tableid])
if (iseditable && params[1] !== 'authordialog') {
emtable.bind('emathtable_changed', function(e){
var $emtplace = jQuery(this);
var data = $emtplace.emathtable('get');
var settings = tiddler.data('emathtable', {});
settings[tableid] = data;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tiddler.setData('emathtable', settings);
config.options.chkAutoSave = autosavestatus;
});
}
}
}
}
//}}}
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|embed wiki syntax formatting inside of HTML content|
The ~HTMLFormatting plugin allows you to ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Documentation
>see [[HTMLFormattingPluginInfo]]
!!!!!Configuration
<<<
Use {{{<hide linebreaks>}}} within HTML content to wiki-style rendering of line breaks. To //always// omit all line breaks from the rendered output, you can set this option:
><<option chkHTMLHideLinebreaks>> ignore all line breaks
which can also be 'hard coded' into your document by adding the following to a tiddler, tagged with <<tag systemConfig>>
>{{{config.options.chkHTMLHideLinebreaks=true;}}}
<<<
!!!!!Revisions
<<<
2010.05.07 2.4.1 added chkHTMLHideLinebreaks option
| see [[HTMLFormattingPluginInfo]] for additional revision details |
2005.06.26 1.0.0 Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormattingPlugin= {major: 2, minor: 4, revision: 1, date: new Date(2010,5,7)};
// find the formatter for HTML and replace the handler
initHTMLFormatter();
function initHTMLFormatter()
{
for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
if (!this.lookaheadRegExp) // fixup for TW2.0.x
this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var html=lookaheadMatch[1];
// if <nowiki> is present, just let browser handle it!
if (html.indexOf('<nowiki>')!=-1)
createTiddlyElement(w.output,"span").innerHTML=html;
else {
// if <hide linebreaks> is present, or chkHTMLHideLinebreaks is set
// suppress wiki-style literal handling of newlines
if (config.options.chkHTMLHideLinebreaks||(html.indexOf('<hide linebreaks>')!=-1))
html=html.replace(/\n/g,' ');
// remove all \r's added by IE textarea and mask newlines and macro brackets
html=html.replace(/\r/g,'').replace(/\n/g,'\\n').replace(/<</g,'%%(').replace(/>>/g,')%%');
// create span, let browser parse HTML
var e=createTiddlyElement(w.output,"span"); e.innerHTML=html;
// then re-render text nodes as wiki-formatted content
wikifyTextNodes(e,w);
}
w.nextMatch = this.lookaheadRegExp.lastIndex; // continue parsing
}
}
}
// wikify #text nodes that remain after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode,w)
{
function unmask(s) { return s.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n'); }
switch (theNode.nodeName.toLowerCase()) {
case 'style': case 'option': case 'select':
theNode.innerHTML=unmask(theNode.innerHTML);
break;
case 'textarea':
theNode.value=unmask(theNode.value);
break;
case '#text':
var txt=unmask(theNode.nodeValue);
var newNode=createTiddlyElement(null,"span");
theNode.parentNode.replaceChild(newNode,theNode);
wikify(txt,newNode,highlightHack,w.tiddler);
break;
default:
for (var i=0;i<theNode.childNodes.length;i++)
wikifyTextNodes(theNode.childNodes.item(i),w); // recursion
break;
}
}
//}}}
|Name|HTMLFormattingPluginInfo|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for HTMLFormattingPlugin|
The ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Usage
<<<
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.
When a tiddler is about to be displayed, ~TiddlyWiki looks for tiddler content contained within {{{<html>}}} and {{{</html>}}} markers. When present, the TiddlyWiki core simply passes this content directly to the browser's internal "rendering engine" to process as ~HTML-formatted content. However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain. This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.
This plugin extends the TiddlyWiki core processing so that, after the HTML formatting has been processed, all the pieces of text occuring within the HTML block are then processed one piece at a time, so that normal wiki-style formatting can be applied to the individual text pieces.
Note: To bypass this extended processing for a specific section of HTML content, embed ''{{{<nowiki>}}}'' //anywhere// inside the {{{<html>...</html>}}} delimiters, and wiki formatting will not be applied to that content.
<<<
!!!!!Line breaks
<<<
One major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.
Even though you can use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.
If removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules, by placing ''{{{<hide linebreaks>}}}'' //anywhere// within the HTML content. This automatically converts all line breaks to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.
Alternatively, if you //always// want to omit all line breaks from the rendered output, you can set this option:
><<option chkHTMLHideLinebreaks>> ignore all line breaks
which can also be 'hard coded' into your document by adding the following to a tiddler, tagged with <<tag systemConfig>>
>{{{config.options.chkHTMLHideLinebreaks=true;}}}
Note: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide linebreaks}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.
<<<
!!!!!How it works
<<<
The TW core support for HTML does not let you put ANY wiki-style syntax (including TW macros) *inside* the {{{<html>...</html>}}} block. Everything between {{{<html>}}} and {{{</html>}}} is handed to the browser for processing and that is it.
However, not all wiki syntax can be safely passed through the browser's parser. Specifically, any TW macros inside the HTML will get 'eaten' by the browser since the macro brackets, {{{<<...>>}}} use the "<" and ">" that normally delimit the HTML/XML syntax recognized by the browser's parser.
Similarly, you can't use InlineJavascript within the HTML because the {{{<script>...</script>}}} syntax will also be consumed by the browser and there will be nothing left to process afterward. Note: unfortunately, even though the browser removes the {{{<script>...</script>}}} sequence, it doesn't actually execute the embedded javascript code that it removes, so any scripts contained inside of <html> blocks in TW are currently being ignored. :-(
As a work-around to allow TW *macros* (but not inline scripts) to exist inside of <html> formatted blocks of content, the plugin first converts the {{{<<}}} and {{{>>}}} into "%%(" and ")%%", making them "indigestible" so they can pass unchanged through the belly of the beast (the browser's HTML parser).
After the browser has done its job, the wiki syntax sequences (including the "undigested" macros) are contained in #text nodes in the browser-generated DOM elements. The plugin then recursively locates and processes each #text node, converts the %%( and )%% back into {{{<<}}} and {{{>>}}}, passes the result to wikify() for further rendering of the wiki-formatted syntax into a containing SPAN that replaces the previous #text node. At the end of this process, none of the encoded %%( and )%% sequences remain in the rendered tiddler output.
<<<
!!!!!Revisions
<<<
2010.05.07 2.4.1 added chkHTMLHideLinebreaks option
2009.01.05 2.4.0 in wikifyTextNodes(), pass w.highlightRegExp and w.tiddler to wikify() so that search term highlighting and tiddler-relative macro processing will work
2008.10.02 2.3.0 added use of {{{<nowiki>}}} marker to bypass all wikification inside a specific HTML block
2008.09.19 2.2.0 in wikifyTextNodes(), don't wikify the contents of STYLE nodes (thanks to MorrisGray for bug report)
2008.04.26 [*.*.*] plugin size reduction: more documentation moved to HTMLFormattingInfo
2008.01.08 [*.*.*] plugin size reduction: documentation moved to HTMLFormattingInfo
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.14 2.1.5 in formatter, removed call to e.normalize(). Creates an INFINITE RECURSION error in Safari!!!!
2006.09.10 2.1.4 update formatter for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.05.28 2.1.3 in wikifyTextNodes(), decode the *value* of TEXTAREA nodes, but don't wikify() its children. (thanks to "ayj" for bug report)
2006.02.19 2.1.2 in wikifyTextNodes(), put SPAN element into tiddler DOM (replacing text node), BEFORE wikifying the text content. This ensures that the 'place' pasced to any macros is correctly defined when the macro is evaluated, so that calls to story.findContainingTiddler(place) will work as expected. (Thanks for bug report from GeoffSlocock)
2006.02.05 2.1.1 wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.01 2.1.0 don't wikify #TEXT nodes inside SELECT and TEXTAREA elements
2005.11.06 2.0.1 code cleanup
2005.10.31 2.0. replaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code
2005.10.09 1.0.2 combined documentation and code into a single tiddleb
2005.08.05 1.0.1 moved HTML and CSS definitions into plugin code instead of using separate tiddlers
2005.07.26 1.0.1 Re-released as a plugin. Added <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling
2005.06.26 1.0.0 Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
<!--{{{-->
<script type="text/javascript" src="data/js/jquery-ui-1.8.16.custom.min.js"></script>
<script src="mathquill/mathquill.js"></script>
<script type="text/javascript" src="data/js/jsxgraphcore.js"></script>
<script type="text/javascript" src="data/js/sdeditor.js"></script>
<!-- <script type="text/javascript" src="data/js/emathbook.js"></script> -->
<!-- <script type="text/javascript" src="data/js/authortools.js"></script> -->
<script type="text/javascript">
(function($) {
/**
* This is for Cross-site Origin Resource Sharing (CORS) requests.
*
* Additionally the script will fail-over to a proxy if you have one set up.
*
* @param string url the url to retrieve
* @param mixed data data to send along with the get request [optional]
* @param function callback function to call on successful result [optional]
* @param string type the type of data to be returned [optional]
*/
$.getCORS = function (url, data, callback, type) {
try {
// Try using jQuery to get data
jQuery.get(url, data, callback, type);
} catch(e) {
// jQuery get() failed, try IE8 CORS, or use the proxy
if (jQuery.browser.msie && window.XDomainRequest) {
// Use Microsoft XDR
var xdr = new XDomainRequest();
xdr.open("get", url);
xdr.onload = function() {
callback(this.responseText, 'success');
};
xdr.send();
} else {
alert('Sorry! No CORS!');
}
}
}
/**
* This method is for Cross-site Origin Resource Sharing (CORS) POSTs
*
* @param string url the url to post to
* @param mixed data additional data to send [optional]
* @param function callback a function to call on success [optional]
* @param string type the type of data to be returned [optional]
*/
$.postCORS = function (url, data, callback, type) {
try {
// Try using jQuery to POST
return jQuery.post(url, data, callback, type);
} catch(e) {
// jQuery POST failed
var params = '';
for (key in data) {
params = params+'&'+key+'='+data[key];
}
// Try XDR, or use the proxy
if (jQuery.browser.msie && window.XDomainRequest) {
// Use XDR
var xdr = new XDomainRequest();
xdr.open("post", url);
xdr.send(params);
xdr.onload = function() {
callback(xdr.responseText, 'success');
};
return xdr;
} else {
alert('Sorry! No CORS!');
}
}
}
})(jQuery);
</script>
<!--}}}-->
<link rel="stylesheet" type="text/css" href="mathquill/mathquill.css" />
<link rel="stylesheet" type="text/css" href="data/css/jsxgraph.css" />
<link type="text/css" href="data/css/sunny/jquery-ui-1.8.16.custom.css" rel="stylesheet" />
<link type="text/css" href="data/css/jquery.dataTables_themeroller.css" rel="stylesheet" />
<!--[if IE 8]><style type="text/css">
.mathquill-rendered-math .paren {vertical-align: top;}
body #contentWrapper #displayArea {
background-color: white;
border: 1px solid black;
border-left: 3px solid black;
border-bottom: 3px solid black;
padding-top: 1em;
}
body #contentWrapper .header {
background-color: #74882D;
}
#mainMenu {
background: #74882D url(./toctext.png) right 50px no-repeat;
}
</style><![endif]-->
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASKSURBVDiNdZV7bBRVFIe/OzO7Q3e7LV1aHrUUAg1QCqHQBiFVQitaaaVGI/FBCpJIQHwgMaAmRFKIShofEK0viBIaHiIJGgFTjQaDIErLK7WLECrPUnZl2+1st53Zmbn+QalK8ST3z9+Xc3PP/Y6QUnJ7CSFUPRCo9I/IrfL4/BP1QNpQgF4jFrZ7Ei3xtqvfWEbnPimlMyB7O1APBCelj8rdUfz0i+NHT5/pTQtmIoTAlRJbQiwS4c/GI9bJrR/8YbVfesqIRpvvCBRCiIyxE2rvmjajes7qmmFpfj+6qqAJgQAcKbGkxLRdzv/4Nd7JJfxSt+F65MSx+tj5ltWyD9QPHJw3sfbeFWtWTC57wJvqUfGpCoNUgSYE9AG7TZOmdUspCc7l1wsHiN9zH1eVVOv0Rxs2JVrPrAZQbl0zZ9rdCwtK7/cGPCppHoXBXpUMr0ZQ18jwaijdXfz2egVzZi1l9qxqNi7cy6MdWWSGTngzp86o1oPBSQCKEEJNH5W7o2xVzTCfpuLXFFI1lTSPSoZXJehVSVw5x8/rK6lbW8biygYSabtoJEJF0eNM6UmncF71cD179HYhhKqovkBF4aIXxvtTfOiKQFcEPlXBrymkeVQuHv2Wpk8Xs7n2YYakxuCvLRRnLmZc5iv8TgfPVb5Kyp63yXpsyQR8gQotNTu3KqdohldRQFUEqvjnHNxei3qtgY3rqqD3HHR8CdJCStDMzzGZQVN4Kr2qSVpBkVcfkVOlaT5fQUowEwDLlXQ7EiVp88N7yyjNizF/eRl0N0LsAODiSrhyHYwEtJ9dxrZTD3Lx2Y+J2+DqvvGalhrIilouva4k3QO2hO0LZlL78nRmlxRC1/cQP3zzpV241A6JXjh0UvBFeznXn3mfTtPhhmlj+9OHaL2263QmHUDFo7jcOH0an+Ly2e4QZsdhyqe1AmA7cOEamBbsP6zQwAI6n6whYdkkHBe7b/wU24iFexyXhOMSTzq07NrEoidKWLOyjMazQ6nbMwgrCa1Xb8J2fqfSkPoSsXk1GLZD3HaJ230/sCsaUeyeeCgWCWMkHWJJB+PcKUqKsrDNDubNySV0eQg/HYekDZ985eFQ3ht0lj5PLOnQZTl0JR2kBGJRSBhnNDvcvi984ugipbRST0qJEYkS6wzjVRPYZifz52bz7pYoGRmSM6V1JCbMJm45/Q0k3T4XhJpMboT3C0D1jClozHlnZ6Fz8gjX3lzO8KwUCvL8tEV6sG0HowdSV35IcmIJCdul23YxbIdbLCwT1i46zvnm6UJKiQgEJ+kl5Q2BKcXZ3kO7scfNxJtfjD6+EKkPwpYSy5X0Oi49tovp3qa8LevbOLK/XBpGswYgjWizGDm23pk2a6W+aqtXEwJLQBxwTBvbvQl07uBOmg5atByrl4bRPEBf5Ix5i/ziahauzkYfNDD87zJ7YVttG6HGeq60vjZAX/2CDAQmkTWynkeW5JNfrJMe/C8oFoVQo8nezSEil6tvddaf/78VgC9QQXDoQ6T48wmkDwXAiIXp6Q4RDe8jYRy40wr4GyUNLD/HVcNdAAAAAElFTkSuQmCC" type="image/png" rel="shortcut icon" />
<script type="text/javascript">translateOnLoad = false;</script>
<!--}}}-->
/***
|''Name:''|MathQuillPlugin|
|''Description:''|This plugin uses [[MathQuill|http://laughinghan.github.com/mathquill/]] to render mathematical formulas in TiddlyWiki.|
|''Version:''|0.1|
|''Source:''|...|
|''Author:''|Petri Salmela, Petri Sallasmaa|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.1.0|
***/
/*{{{*/
config.formatterHelpers.MathQuillHelper = function(w){
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookahead = this.lookaheadRegExp.exec(w.source);
if (lookahead){
var parent = w.output;
if (this.displaystyle){
var node = createTiddlyElement(parent, 'div', null, 'mathdisplaystyle');
parent = node;
}
var node = createTiddlyElement(parent, 'span', null, 'mathquill-embedded-latex', lookahead[1]);
node.title = lookahead[1];
if (!this.displaystyle && typeof(jQuery.browser.msie) != 'undefined' && jQuery.browser.msie && parseInt(jQuery.browser.version) == 8){
jQuery(node).mathquill().css('width', jQuery(node).width()+3);
} else {
jQuery(node).mathquill();
}
w.nextMatch = lookahead.index + lookahead[0].length;
}
}
config.formatters.push({
name: 'cmathquill',
match: '\\\\\\[',
lookaheadRegExp: /\\\[((?:.|\n)*?)\\\]/mg,
displaystyle: true,
handler: config.formatterHelpers.MathQuillHelper
});
config.formatters.push({
name: 'cmathquilldollar',
match: '\\$\\$',
lookaheadRegExp: /\$\$((?:.|\n)*?)\$\$/mg,
displaystyle: true,
handler: config.formatterHelpers.MathQuillHelper
});
config.formatters.push({
name: 'mathquill',
match: '\\\\\\(',
lookaheadRegExp: /\\\(((?:.|\n)*?)\\\)/mg,
displaystyle: false,
handler: config.formatterHelpers.MathQuillHelper
});
config.formatters.push({
name: 'mathquilldollar',
match: '\\$',
lookaheadRegExp: /\$((?:.|\n)*?)\$/mg,
displaystyle: false,
handler: config.formatterHelpers.MathQuillHelper
});
/***************************************
* Use <span class="eblinebreak"></span> for linebreaks instead of <br>. Easier and more flexible to style.
***************************************/
(function(){
var findex;
for (findex = 0; findex < config.formatters.length; findex++){
if (config.formatters[findex].name == 'lineBreak') {break;}
}
config.formatters.splice(findex,0,{
name: 'brreplace',
match: '\n|<br ?/?>',
handler: function(w){
createTiddlyElement(w.output, 'span', null, 'eblinebreak');
}
});
config.formatters.splice(findex,0,{
name: 'parbreak',
match: '\n\n+',
handler: function(w){
createTiddlyElement(w.output, 'span', null, 'ebparbreak');
}
});
})()
/*}}}*/
//{{{
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
config.macros.mqpanel = {
/******************************
* Show mqpanel
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length > 0 && params[0].substr(0,1) === '#'){
var $mqplace = jQuery(params[0]);
} else {
wikify('<html><div id="mathquillpanel"></div></html>', place);
var $mqplace = jQuery(place).find('#mathquillpanel');
}
$mqplace.mqpanel();
}
};
};
//}}}
//{{{
/**************************************************************
* Button panel for Mathquill editable boxes.
* 29.10.2012
* Petri Salmela (pesalmel@abo.fi)
* Petri Sallasmaa (pekasa@utu.fi)
* E-math project ( http://emath.eu )
**************************************************************/
(function($){
// jQuery plugin
$.fn.mqpanel = function(options){
// Test for mqpanel commands and trigger command with options.
if (typeof(options) === 'string'){
var cmd = options;
options = arguments[1] || {};
if (typeof(options) === 'string'){
options = {name: options};
}
// Placeholder variable for returning value.
options.result = this;
this.trigger(cmd, options);
return options.result;
}
// Extend default settings with user given options.
var settings = $.extend({
theme: "default_theme", // html class for other styling
orientation: 'vertical',
positionx: 0,
positiony: 100,
refvert: 'free',
refhoriz: 'right',
float: false,
open: true
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
// Create new MqPanel object.
var mqpanel = new MqPanel(this, settings);
testilogit.mqpanel = mqpanel;
});
}
var MqPanel = function(place, settings){
var mqpanel = this;
this.place = $(place);
this.islocalstorage = MqPanel.supports_html5_storage();
this.settings = {};
this.settings.orientation = settings.orientation;
this.settings.positionx = settings.positionx;
this.settings.positiony = settings.positiony;
this.settings.refvert = settings.refvert;
this.settings.refhoriz = settings.refhoriz;
if (settings.float){
this.settings.refvert = 'free';
this.settings.refhoriz = 'free';
}
this.settings.iscatopen = settings.open;
this.loadSettings();
this.categories = [];
this.categorymap = {};
this.addCategories();
this.draw();
}
MqPanel.prototype.draw = function(){
var mqpanel = this;
this.place.empty().addClass('mqpanel_wrapper').css('position','fixed')
.append('<div class="mqpanel"><div class="mqpanel_handle"></div><div class="mqpanel_main"><a href="javascript:;" class="mqpanel_mainbutton"><span>✪</span></a></div><div class="mqbuttonwrapper" style="display: inline-block;">'+this.getHtml()+'<div class="mqpanelsettings"><a href="javascript:;" class="mqpanelsettings_button">⚙</a></div></div></div>');
this.panel = this.place.find('.mqpanel');
this.content = this.place.find('.mqbuttonwrapper');
this.settingscontainer = this.place.find('.mqpanelsettings');
if (this.settings.iscatopen){
this.openCategories(true);
}
// Add css styles if they don't exist already.
if ($('head style#mqpanelstyle').length === 0){
$('head').append('<style id="mqpanelstyle" type="text/css">'+MqPanel.strings['style']+'</style>');
}
// Make draggable, if jQuery-ui exists.
if (typeof($.fn.draggable) === 'function'){
this.place.draggable({
disabled: true,
handle: '.mqpanel_handle',
snap: 'document',
snapMode: 'inner',
containment: 'document',
cursor: 'move',
stop: function(event, ui){
mqpanel.updateAttrs();
}
}).css({height:'', width:''});
}
// Use current settings.
this.useSettings();
// Make sure, all attributes are applied to all elements.
this.updateAttrs();
// Init events
this.initEvents();
}
MqPanel.prototype.initEvents = function(){
var mqpanel = this;
// addbuttons -event
this.place.bind('addbuttons', function(e, options){
mqpanel.addCategories(options.categories);
mqpanel.draw();
});
// removebuttons -event
this.place.bind('removebuttons', function(e, options){
mqpanel.removeCategory(options.name);
mqpanel.draw();
});
// Focusout on Mathquill-element to save "lastfocus".
jQuery('body').delegate('.mathquill-editable', 'focusout.mqpanel', function(e){
mqpanel.lastfocus = $(this);
});
// Click on elsewhere closes categories
jQuery('html').bind('click.mqpanel', function(e){
mqpanel.panel.find('li.mqpanelcategory.isopen a.mqpanelcatbutton').click();
});
// Minimize / maximize
this.panel.find('a.mqpanel_mainbutton').click(function(e){
var button = $(this);
var parent = button.parents('div.mqpanel');
if (parent.hasClass('isopen')){
mqpanel.closeCategories();
} else {
mqpanel.openCategories();
}
});
// Category buttons
this.panel.find('ul.mqpanel_categories a.mqpanelcatbutton').click(function(e){
var button = $(this);
var parent = button.parents('li.mqpanelcategory');
if (parent.hasClass('isopen')){
parent.removeClass('isopen');
} else {
parent.siblings('li.mqpanelcategory').removeClass('isopen');
mqpanel.panel.find('.isopen a.mqpanelsettings_button').click();
parent.addClass('isopen');
}
mqpanel.lastfocus && mqpanel.lastfocus.focus();
return false;
});
// LaTeX-buttons
this.panel.find('ul.mqpanel_categories ul.mqpanel_buttons li.mqpanelbutton a').click(function(e){
if (typeof(mqpanel.lastfocus) === 'undefined'){
return false;
}
var latex = jQuery(this).attr('title');
var has_inside = jQuery(this).attr('inside');
var $mathquillelem = jQuery(mqpanel.lastfocus);
if ($mathquillelem.focus().find('.cursor').parent().hasClass('text') || $mathquillelem.focus().find('.cursor').parent().hasClass('mathquill-textbox')){
return false;
}
var data = $mathquillelem.data('[[mathquill internal data]]');
var block = data && data.block;
var cursor = block && block.cursor;
var selection ='';
if (cursor && cursor.selection){
var selection = cursor.selection.latex();
}
if(selection !== ''){
if( has_inside === '1' ){
$mathquillelem.mathquill('write',latex + '{'+selection + '}');
}else if (has_inside === '2'){
$mathquillelem.mathquill('write',latex + '{'+selection + '}{}');
}else if (has_inside === '('){
$mathquillelem.mathquill('write',latex);
cursor.moveLeft();
$mathquillelem.mathquill('write',selection);
}else if (has_inside === '()'){
var parts = latex.split(' ');
$mathquillelem.mathquill('write',parts[0] + selection + parts[1]);
}else{
$mathquillelem.mathquill('write',latex);
}
}else{
$mathquillelem.mathquill('write',latex);
if (has_inside === '(' || has_inside === '()'){
cursor.moveLeft();
}
}
$mathquillelem.focus();
if (cursor){
var moves = parseInt(has_inside);
var goright = moves < 0;
moves = Math.abs(moves);
for (var movement = 0; movement < moves; movement ++){
if (goright){
cursor.moveRight();
} else {
cursor.moveLeft();
}
}
}
return false;
});
// Settings dialog
this.settingscontainer.find('a.mqpanelsettings_button').click(function(e){
mqpanel.showHideSettings();
});
}
MqPanel.prototype.openCategories = function(fast){
if (fast || this.settings.orientation === 'horizontal'){
this.content.show().css('display','');
} else {
this.content.slideDown(200, function(){$(this).css('display','')});
}
this.panel.addClass('isopen');
this.settings.iscatopen = true;
this.saveSettings();
}
MqPanel.prototype.closeCategories = function(fast){
var mqpanel = this;
if (fast || this.settings.orientation === 'horizontal'){
this.place.css({width: '', height: ''});
this.content.hide();
} else {
this.content.slideUp(200, function(){mqpanel.place.css({width: '', height: ''});});
}
this.panel.removeClass('isopen');
this.settings.iscatopen = false;
this.saveSettings();
}
MqPanel.prototype.addCategories = function(data){
if (typeof(data) === 'undefined'){
data = MqPanel.buttonCategories;
}
for (var i = 0; i < data.length; i++){
if (!(data[i].name in this.categorymap)){
var newcat = new MqPanelCategory(data[i]);
this.categorymap[newcat.name] = this.categories.length;
this.categories.push(newcat);
}
}
}
MqPanel.prototype.removeCategory = function(name){
if (name in this.categorymap){
this.categories.splice(this.categorymap[name], 1);
this.categorymap = {};
for (var i = 0; i < this.categories.length; i++){
this.categorymap[this.categories[i].name] = i;
}
}
}
MqPanel.prototype.getHtml = function(){
var html = '<ul class="mqpanel_categories">';
for (var i = 0; i < this.categories.length; i++){
html += '<li class="mqpanelcategory">'+this.categories[i].getHtml()+'</li>';
}
html += '</ul>';
return html;
}
MqPanel.prototype.loadSettings = function(){
if (this.islocalstorage){
var settings = JSON.parse(localStorage.getItem('mqpanelsettings') || '{}');
jQuery.extend(true, this.settings, settings);
}
}
MqPanel.prototype.saveSettings = function(){
if (this.islocalstorage){
localStorage.setItem('mqpanelsettings', JSON.stringify(this.settings));
}
}
MqPanel.prototype.showHideSettings = function(){
if (this.settingscontainer.hasClass('isopen')){
this.settingscontainer.removeClass('isopen').find('.mqpanel_settingsselector').remove();
} else {
var mqpanel = this;
var html = '<div class="mqpanel_settingsselector">';
html += '<table class="mqpanel_position"><tbody>';
html += '<tr><td><a href="javascript:;" settings="refvert refhoriz" values="top left"><span>◰</span></a><td><td><a href="javascript:;" settings="refvert refhoriz orientation" values="top free horizontal"><span>⬒</span></a><td><td><a href="javascript:;" settings="refvert refhoriz" values="top right"><span>◳</span></a><td></tr>';
html += '<tr><td><a href="javascript:;" settings="refvert refhoriz orientation" values="free left vertical"><span>◧</span></a><td><td><a href="javascript:;" settings="refvert refhoriz" values="free free"><span>▣</span></a><td><td><a href="javascript:;" settings="refvert refhoriz orientation" values="free right vertical"><span>◨</span></a><td></tr>';
html += '<tr><td><a href="javascript:;" settings="refvert refhoriz" values="bottom left"><span>◱</span></a><td><td><a href="javascript:;" settings="refvert refhoriz orientation" values="bottom free horizontal"><span>⬓</span></a><td><td><a href="javascript:;" settings="refvert refhoriz" values="bottom right"><span>◲</span></a><td></tr>';
html += '</tbody></table>';
html += '<ul class="mqpanel_orientation"><li><a href="javascript:;" settings="orientation" values="horizontal">↔</a></li><li><a href="javascript:;" settings="orientation" values="vertical">↕</a></li></ul>';
html += '</div>';
this.settingscontainer.addClass('isopen').append(html);
this.settingscontainer.find('.mqpanel_position a, .mqpanel_orientation a').click(function(e){
var button = $(this);
var settings = button.attr('settings').split(' ');
var values = button.attr('values').split(' ');
for (var i = 0; i < settings.length; i++){
mqpanel.settings[settings[i]] = values[i];
}
mqpanel.saveSettings();
mqpanel.useSettings();
mqpanel.updateAttrs();
var posx = mqpanel.place.position().left;
var posy = mqpanel.place.position().top;
var panheight = mqpanel.place.height() + parseInt(mqpanel.place.css('margin-top')) + parseInt(mqpanel.place.css('margin-bottom'));
var panwidth = mqpanel.place.width() + parseInt(mqpanel.place.css('margin-left')) + parseInt(mqpanel.place.css('margin-right'));
if (posy + panheight > $(window).height()){
mqpanel.settings.positiony = $(window).height() - panheight;
}
if (posx + panwidth > $(window).width()){
mqpanel.settings.positionx = $(window).width() - panwidth;
}
mqpanel.saveSettings();
mqpanel.useSettings();
mqpanel.settingscontainer.find('a.mqpanelsettings_button').click();
});
}
}
MqPanel.prototype.useSettings = function(){
this.place.attr('refvert', this.settings.refvert);
this.place.attr('refhoriz', this.settings.refhoriz);
this.place.attr('orientation', this.settings.orientation);
this.place.css({width: '', height: '', top: 0, left: 0, bottom: 'auto', right: 'auto'});
var width = this.place.width();
var height = this.place.height();
this.place.css({top: '', left: '', bottom: '', right: ''});
if (this.settings.refvert === 'free' && this.settings.refhoriz === 'free'){
this.place.draggable('option', 'disabled', false).draggable('option', 'axis', false);
this.place.css({'top': this.settings.positiony, 'left': this.settings.positionx});
} else if (this.settings.refvert === 'free'){
this.place.draggable('option', 'disabled', false).draggable('option', 'axis', 'y');
this.place.css({'top': this.settings.positiony, 'left': '', 'right': ''});
} else if (this.settings.refhoriz === 'free'){
this.place.draggable('option', 'disabled', false).draggable('option', 'axis', 'x');
this.place.css({'top': '', 'bottom': '', 'left': this.settings.positionx});
} else {
this.place.draggable('option', 'disabled', true).draggable('option', 'axis', false);
this.place.css({'top': '', 'bottom': '', 'left': '', 'right': ''});
}
if (!(height > $(document).height() && width > 300)){
this.place.css({width: width+'px', height: height+'px'});
}
}
MqPanel.prototype.updateAttrs = function(){
var mqpanel = this;
if (mqpanel.place.is(':visible')){
var pos = mqpanel.place.position();
mqpanel.settings.positionx = pos.left;
mqpanel.settings.positiony = pos.top;
mqpanel.saveSettings();
}
if (mqpanel.settings.positiony > $(window).height() / 2){
mqpanel.place.attr('verthalf','bottom');
} else {
mqpanel.place.attr('verthalf','top');
}
if (mqpanel.settings.positionx > $(window).width() / 2){
mqpanel.place.attr('horizhalf','right');
} else {
mqpanel.place.attr('horizhalf','left');
}
if (mqpanel.settings.orientation === 'horizontal'){
mqpanel.place.find('.mqbuttonwrapper').css('display','');
}
}
/**********************************************************
* Strings: css-styles etc.
**********************************************************/
MqPanel.strings = {
style: '/* Hide mathpanel of sdeditor*/'
+'#mathbuttonwrapper #mathbuttonpanel {display: none;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory ul.mqpanel_buttons, .mqpanel_wrapper .mqpanelsettings .mqpanel_settingsselector,'
+'.mqpanel_wrapper .mqpanel {border-radius: 6px; box-shadow: 3px 3px 8px rgba(0,0,0,0.5); border: 1px solid #1ACEFA;'
+'background: rgb(214,249,255); /* Old browsers */'
+'background: -moz-linear-gradient(top, rgba(214,249,255,1) 0%, rgba(158,232,250,1) 100%); /* FF3.6+ */'
+'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(214,249,255,1)), color-stop(100%,rgba(158,232,250,1))); /* Chrome,Safari4+ */'
+'background: -webkit-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* Chrome10+,Safari5.1+ */'
+'background: -o-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* Opera 11.10+ */'
+'background: -ms-linear-gradient(top, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* IE10+ */'
+'background: linear-gradient(to bottom, rgba(214,249,255,1) 0%,rgba(158,232,250,1) 100%); /* W3C */'
+'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#d6f9ff\', endColorstr=\'#9ee8fa\',GradientType=0 ); /* IE6-9 */'
+'}'
+'.mqpanel_wrapper {position: fixed; z-index: 201; font-size: 20px;}'
+'.mqpanel_wrapper.ui-state-disabled {opacity: 1;}'
+'.mqpanel_wrapper a:hover {background-color: transparent;}'
+'.mqpanel_wrapper[refvert="top"] {top: 0;}'
+'.mqpanel_wrapper[refvert="bottom"] {bottom: 0;}'
+'.mqpanel_wrapper[refhoriz="left"] {left: 0;}'
+'.mqpanel_wrapper[refhoriz="right"] {right: 0;}'
+'.mqpanel_wrapper .mqpanel_handle {min-height: 15px; min-width: 15px; background: #faa; border-radius: 6px 6px 0 0; cursor: move;}'
+'.mqpanel_wrapper .mqpanel {padding: 0; padding-bottom: 10px; white-space: nowrap;}'
+'.mqpanel_wrapper .mqpanel a {text-decoration: none; color: blue; text-shadow: 2px 2px 1px white;}'
+'.mqpanel_wrapper .mqpanel a.mqpanel_mainbutton {display: block; height: 30px; min-width: 40px; text-align: center; line-height: 30px;}'
+'.mqpanel_wrapper .mqpanel_main {border-bottom: 1px solid #1ACEFA; margin: 0 4px;}'
+'.mqpanel_wrapper .mqpanel a.mqpanel_mainbutton span {vertical-align: middle;}'
+'.mqpanel_wrapper ul.mqpanel_categories {display: none; list-style: none; margin: 0 4px; padding: 0;}'
+'.mqpanel_wrapper .mqpanel.isopen ul.mqpanel_categories {display: block; list-style: none; margin: 0 4px; padding: 0;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory {margin: 0; position: relative; text-align: center; padding: 2px; border-bottom: 1px solid #1ACEFA; border-top: 1px solid white;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory.isopen a.mqpanelcatbutton,'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory.isopen:hover a.mqpanelcatbutton {border-radius: 6px; border: 1px solid red; box-shadow: inset 0 0 10px rgba(255,0,0,0.5); background: white;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory:hover a.mqpanelcatbutton {border: 1px solid white;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory a.mqpanelcatbutton {display: block; width: 30px; height: 30px; line-height: 30px; border: 1px solid transparent; border-radius: 6px;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory a.mqpanelcatbutton span {vertical-align: middle;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory ul.mqpanel_buttons {position: absolute; left: 35px; top: 0; text-align: left; display: none; list-style: none; width: 78px; margin: 0; padding: 0; border-radius: 6px; white-space: normal;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {display: block;}'
+'.mqpanel_wrapper ul.mqpanel_categories ul.mqpanel_buttons li.mqpanelbutton {display: inline-block; width: 40px; height: 30px; margin: 0; padding: 0; padding: 2px; border-radius: 4px; border: 1px solid transparent; text-align: center; line-height: 30px;}'
+'.mqpanel_wrapper ul.mqpanel_categories ul.mqpanel_buttons li.mqpanelbutton:hover {border: 1px solid white;}'
+'.mqpanel_wrapper ul.mqpanel_categories ul.mqpanel_buttons li.mqpanelbutton a {display: block;}'
+'.mqpanel_wrapper a.mqpanelsettings_button {display: block; height: 30px; width: 30px; margin: 0 auto; text-align: center; line-height: 30px; vertical-align: middle; border-radius: 6px; border: 1px solid transparent;}'
+'.mqpanel_wrapper a.mqpanelsettings_button:hover {border: 1px solid white;}'
+'.mqpanel_wrapper .mqpanelsettings {position: relative; border-top: 1px solid white; margin: 0 4px; padding: 2px;}'
+'.mqpanel_wrapper .mqpanelsettings.isopen .mqpanelsettings_button {border: 1px solid red; box-shadow: inset 0 0 10px rgba(255,0,0,0.5); background: white;}'
+'.mqpanel_wrapper .mqpanel_settingsselector {position: absolute; left: 40px; bottom: 0; text-align: left; margin: 0; padding: 0; border-radius: 6px;}'
+'.mqpanel_wrapper[refhoriz="left"] .mqpanel_settingsselector {left: 40px; right: auto; bottom: 0; top: auto;}'
+'.mqpanel_wrapper[refhoriz="right"] .mqpanel_settingsselector {left: auto; right: 40px; bottom: 0; top: auto;}'
+'.mqpanel_wrapper[refhoriz="right"] li.mqpanelcategory.isopen ul.mqpanel_buttons {left: auto; right: 40px;}'
+'.mqpanel_wrapper[refvert="top"] .mqpanel_settingsselector {top: auto; bottom: 0;}'
+'.mqpanel_wrapper[refvert="bottom"] .mqpanel_settingsselector {top: auto; bottom: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqpanel_handle {display: block; border-radius: 6px 0 0 6px; margin: 1px; position: absolute; left:0; top: 0; bottom: 0;}'
+'.mqpanel_wrapper[refvert="bottom"] .mqpanel_handle {border-radius: 6px 0 0 0;}'
+'.mqpanel_wrapper[refvert="top"] .mqpanel_handle {border-radius: 0 0 0 6px;}'
+'.mqpanel_wrapper[refhoriz="left"] .mqpanel_handle {border-radius: 0 6px 0 0;}'
+'.mqpanel_wrapper[refhoriz="right"] .mqpanel_handle {border-radius: 6px 0 0 0;}'
+'.mqpanel_wrapper[refvert="top"][refhoriz="left"] .mqpanel_handle, .mqpanel_wrapper[refvert="top"][refhoriz="right"] .mqpanel_handle, .mqpanel_wrapper[refvert="bottom"][refhoriz="left"] .mqpanel_handle, .mqpanel_wrapper[refvert="bottom"][refhoriz="right"] .mqpanel_handle {display: none;}'
+'.mqpanel_wrapper[refvert="top"][refhoriz="left"] .mqpanel_main, .mqpanel_wrapper[refvert="top"][refhoriz="right"] .mqpanel_main, .mqpanel_wrapper[refvert="bottom"][refhoriz="left"] .mqpanel_main, .mqpanel_wrapper[refvert="bottom"][refhoriz="right"] .mqpanel_main {margin-left: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqpanel {padding-right: 10px; padding-bottom: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqpanel_main {display: inline-block; margin: 2px 0 2px 15px; border-right: 1px solid #1ACEFA; border-bottom: none;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqbuttonwrapper {display: inline-block; margin: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqbuttonwrapper ul.mqpanel_categories {display: inline-block; margin: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqbuttonwrapper ul.mqpanel_categories li.mqpanelcategory {display: inline-block; padding: 0 4px; border-right: 1px solid #1ACEFA; border-left: 1px solid white; border-top: none; border-bottom: none; border-radius: 0; margin: 2px 0;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqpanelsettings {display: inline-block; border-left: 1px solid white; border-top: none; padding-left: 4px; margin: 4px 0;}'
+'.mqpanel_wrapper[orientation="horizontal"][verthalf="bottom"] .mqpanel_settingsselector {top: auto; bottom: 36px;}'
+'.mqpanel_wrapper[orientation="horizontal"] ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {top: 36px; bottom: auto;}'
+'.mqpanel_wrapper[orientation="horizontal"] .mqpanel_settingsselector {top: 36px; bottom: auto; left: auto; right: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"][refvert="top"] .mqpanel_settingsselector {top: 36px; left: auto; right: 0; bottom: auto;}'
+'.mqpanel_wrapper[orientation="horizontal"][refvert="bottom"] .mqpanel_settingsselector {top: auto; bottom: 40px; left: auto; right: 0;}'
+'.mqpanel_wrapper ul.mqpanel_categories li.mqpanelcategory ul.mqpanel_buttons, .mqpanel_wrapper .mqpanelsettings .mqpanel_settingsselector {z-index: 21;}'
+'.mqpanel_wrapper[orientation="vertical"][verthalf="bottom"] ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {top: auto; bottom: 0;}'
+'.mqpanel_wrapper[orientation="vertical"][horizhalf="right"] ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {left: auto; right: 36px;}'
+'.mqpanel_wrapper[orientation="vertical"][horizhalf="right"] .mqpanel_settingsselector {left: auto; right: 40px;}'
+'.mqpanel_wrapper[orientation="horizontal"][verthalf="bottom"] ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {top: auto; bottom: 36px;}'
+'.mqpanel_wrapper[orientation="horizontal"][horizhalf="right"] ul.mqpanel_categories li.mqpanelcategory.isopen ul.mqpanel_buttons {left: auto; right: 0;}'
+'.mqpanel_wrapper[orientation="horizontal"][verthalf="bottom"] .mqpanel_settingsselector {top: auto; bottom: 36px;}'
+'.mqpanel_wrapper[orientation="horizontal"][horizhalf="right"] .mqpanel_settingsselector {left: auto; right: 0;}'
+'.mqpanel_wrapper[refhoriz="left"] .mqpanel {border-radius: 0 6px 6px 0; box-shadow: 3px 3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper[refhoriz="right"] .mqpanel {border-radius: 6px 0 0 6px; box-shadow: -3px 3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper[refvert="top"] .mqpanel {border-radius: 0 0 6px 6px; box-shadow: 3px 3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper[refvert="bottom"] .mqpanel {border-radius: 6px 6px 0 0; box-shadow: 3px -3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper[refhoriz="right"] .mqpanel_settingsselector {box-shadow: -3px 3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper[refvert="bottom"] .mqpanel_settingsselector {box-shadow: 3px -3px 8px rgba(0,0,0,0.5);}'
+'.mqpanel_wrapper ul.mqpanel_orientation {list-style: none; text-align: center; font-size: 110%; font-weight: bold; margin: 0; padding: 0; border-top: 1px solid #1ACEFA;}'
+'.mqpanel_wrapper ul.mqpanel_orientation li {display: inline-block; padding: 0 4px; margin: 2px;}'
+'.mqpanel_wrapper ul.mqpanel_orientation li a {display: block;}'
+'.mqpanel_wrapper[orientation="horizontal"] ul.mqpanel_orientation a[values="horizontal"], .mqpanel_wrapper[orientation="vertical"] ul.mqpanel_orientation a[values="vertical"],'
+'.mqpanel_wrapper[refvert="top"][refhoriz="left"] .mqpanel_position a[values="top left"],'
+'.mqpanel_wrapper[refvert="top"][refhoriz="free"] .mqpanel_position a[values="top free horizontal"],'
+'.mqpanel_wrapper[refvert="top"][refhoriz="right"] .mqpanel_position a[values="top right"],'
+'.mqpanel_wrapper[refvert="free"][refhoriz="left"] .mqpanel_position a[values="free left vertical"],'
+'.mqpanel_wrapper[refvert="free"][refhoriz="free"] .mqpanel_position a[values="free free"],'
+'.mqpanel_wrapper[refvert="free"][refhoriz="right"] .mqpanel_position a[values="free right vertical"],'
+'.mqpanel_wrapper[refvert="bottom"][refhoriz="left"] .mqpanel_position a[values="bottom left"],'
+'.mqpanel_wrapper[refvert="bottom"][refhoriz="free"] .mqpanel_position a[values="bottom free horizontal"],'
+'.mqpanel_wrapper[refvert="bottom"][refhoriz="right"] .mqpanel_position a[values="bottom right"]'
+'{color: red;}'
+'.mqpanel_wrapper[refvert="bottom"][refhoriz="free"] ul.mqpanel_orientation, .mqpanel_wrapper[refvert="top"][refhoriz="free"] ul.mqpanel_orientation, .mqpanel_wrapper[refvert="free"][refhoriz="left"] ul.mqpanel_orientation, .mqpanel_wrapper[refvert="free"][refhoriz="right"] ul.mqpanel_orientation {display: none;}'
}
/*******************************************************
* Button category
*******************************************************/
var MqPanelCategory = function(data){
if (!data.name || !data.icon || typeof(data.elements) === 'undefined' || typeof(data.elements.length) !== 'number'){
return false;
}
this.name = data.name;
this.icon = data.icon;
this.icontype = (data.icon.substr(0,5) === 'data:' ? 'data' : (data.icon.substr(0,5) === 'file:' || data.icon.substr(0,5) === 'http:' ? 'image' : 'text'));
this.buttons = [];
for (var i = 0; i < data.elements.length; i++){
var newbutton = new MqPanelButton(data.elements[i]);
this.buttons.push(newbutton);
}
}
MqPanelCategory.prototype.getHtml = function(){
var style, text;
var width = Math.ceil(Math.sqrt(this.buttons.length)) * 46;
switch (this.icontype){
case 'data':
case 'image':
style = 'background-image: url(' + this.icon + ');';
text = '';
break;
case 'text':
style = '';
text = this.icon;
break;
default:
style = '';
text = 'C';
}
var html = '<a href="javascript:;" class="mqpanelcatbutton" style="'+style+'" title="'+this.name+'"><span>'+text+'</span></a>';
html += '<ul class="mqpanel_buttons" style="width: '+width+'px;">';
for (var i = 0; i < this.buttons.length; i++){
html += '<li class="mqpanelbutton">' + this.buttons[i].getHtml() + '</li>';
}
html += '</ul>';
return html;
}
/*******************************************************
* Button
*******************************************************/
var MqPanelButton = function(data){
if (!data.name || !data.icon || !data.latex){
return false;
}
this.name = data.name;
this.icon = data.icon;
this.icontype = (data.icon.substr(0,5) === 'data:' ? 'data' : (data.icon.substr(0,5) === 'file:' || data.icon.substr(0,5) === 'http:' ? 'image' : 'text'));
this.latex = data.latex;
this.inside = data.inside || '';
this.style = data.style || '';
}
MqPanelButton.prototype.getLatex = function(){
return this.latex;
}
MqPanelButton.prototype.getHtml = function(){
var style, text;
switch (this.icontype){
case 'data':
case 'image':
style = 'background-image: url(' + this.icon + ');';
text = '';
break;
case 'text':
style = (this.style === 'small' ? 'font-size: 75%;' : '');
text = this.icon;
break;
default:
style = '';
text = 'B';
}
return '<a href="javascript:;" style="'+style+'" title="'+this.latex+'"'+ (this.inside ? ' inside="'+this.inside+'"' : '')+'>'+text+'</a>';
}
MqPanel.supports_html5_storage = function() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
MqPanel.buttonCategories = [
{
'name' : 'relations',
'icon' : '⇔',
'elements' : [
{
'name' : 'equal',
'latex' : '= ',
'icon' : '='
},
{
'name' : 'lessthan',
'latex' : '\\lt ',
'icon' : '<'
},
{
'name' : 'greaterthan',
'latex' : '\\gt ',
'icon' : '>'
},
{
'name' : 'lessorequalthan',
'latex' : '\\leq ',
'icon' : '≤'
},
{
'name' : 'greaterorequalthan',
'latex' : '\\geq ',
'icon' : '≥'
},
{
'name' : 'notequal',
'latex' : '\\neq ',
'icon' : '≠'
},
{
'name' : 'leftimp',
'latex' : '\\Leftarrow ',
'icon' : '⇐'
},
{
'name' : 'rightimp',
'latex' : '\\Rightarrow ',
'icon' : '⇒'
},
{
'name' : 'eqvivalent',
'latex' : '\\iff ',
'icon' : '⇔'
}
]
},
{
'name' : 'misc',
'icon' : '<i>x</i><sup>2</sup>',
'elements' : [
{
'name' : 'frac',
'latex' : '\\frac ',
'icon' : '/',
'inside': '2'
},
{
'name' : 'centerdot',
'latex' : '\\cdot ',
'icon' : '⋅'
},
{
'name' : 'sqroot',
'latex' : '\\sqrt ',
'icon' : '√',
'inside' : '1'
},
{
'name' : '3rdroot',
'latex' : '\\nthroot 3',
'icon' : '∛',
'inside' : '1'
},
{
'name' : 'nthroot',
'latex' : '\\nthroot ',
'icon' : '<sup>n</sup>√',
'inside' : '2'
},
{
'name' : 'sub',
'latex' : '_',
'icon' : 'X<sub style="color: red; font-weight: bold;">2</sub>',
'inside' : '1'
},
{
'name' : 'sup',
'latex' : '^',
'icon' : 'X<sup style="color: red; font-weight: bold;">2</sup>',
'inside' : '1'
},
{
'name' : 'bar',
'latex' : '\\bar ',
'icon' : '<span style="border-top: 2px solid red;">X</span>',
'inside': '1'
},
{
'name' : 'underline',
'latex' : '\\underline ',
'icon' : '<span style="border-bottom: 2px solid red;">X</span>',
'inside': '1'
},
{
'name' : 'isin',
'latex' : '\\in ',
'icon' : '∈'
},
{
'name' : 'notin',
'latex' : '\\notin ',
'icon' : '∉'
},
{
'name' : 'logicalor',
'latex' : '\\lor ',
'icon' : '∨'
},
{
'name' : 'logicaland',
'latex' : '\\and ',
'icon' : '∧'
},
{
'name' : 'logicalnot',
'latex' : '\\not ',
'icon' : '¬'
},
{
'name' : 'infinity',
'latex' : '\\inf ',
'icon' : '∞'
},
{
'name' : 'empty',
'latex' : '\\emptyset ',
'icon' : '∅'
},
{
'name' : 'angle',
'latex' : '\\angle ',
'icon' : '∠'
},
{
'name' : 'degree',
'latex' : '^{\\circ } ',
'icon' : '°'
},
{
'name' : 'approx',
'latex' : '\\approx ',
'icon' : '≈'
},
{
'name' : 'plusminus',
'latex' : '\\pm ',
'icon' : '±'
},
{
'name' : 'minusplus',
'latex' : '\\mp ',
'icon' : '∓'
},
{
'name' : 'pipe',
'latex' : '\\mid ',
'icon' : '|'
},
{
'name' : 'integral',
'latex' : '\\int ',
'icon' : '∫'
},
{
'name' : 'defined integral',
'latex' : '\\int_{}^{} ',
'icon' : '∫<sub style="position: relative; bottom: -0.4em; left: -0.2em;"><sub>0</sub></sub><sup style="position: relative; left: -0.5em; top: -0.2em;"><sub>1</sub></sup>',
'inside': '3'
},
{
'name' : 'sum',
'latex' : '\\sum ',
'icon' : 'Σ'
},
{
'name' : 'sum',
'latex' : '\\sum_{}^{} ',
'icon' : 'Σ<sup style="position: relative; top: 0.2em;"><sup>n</sup></sup><sub style="position: relative; left: -0.5em;"><sub>i=0</sub></sub>',
'inside': '3'
}
]
},
{
'name' : 'numberfields',
'icon' : 'ℕ',
'elements' : [
{
'name' : 'natural',
'latex' : '\\NN ',
'icon' : 'ℕ'
},
{
'name' : 'integer',
'latex' : '\\ZZ ',
'icon' : 'ℤ'
},
{
'name' : 'posintegers',
'latex' : '\\ZZ_+ ',
'icon' : 'ℤ<sub>+</sub>'
},
{
'name' : 'negintegers',
'latex' : '\\ZZ_- ',
'icon' : 'ℤ<sub>-</sub>'
},
{
'name' : 'rational',
'latex' : '\\QQ ',
'icon' : 'ℚ'
},
{
'name' : 'real',
'latex' : '\\RR ',
'icon' : 'ℝ'
},
{
'name' : 'posreal',
'latex' : '\\RR_+ ',
'icon' : 'ℝ<sub>+</sub>'
},
{
'name' : 'negreal',
'latex' : '\\RR_- ',
'icon' : 'ℝ<sub>-</sub>'
}
]
},
{
'name' : 'greeks',
'icon' : 'α',
'elements' : [
{
'name' : 'alpha',
'latex' : '\\alpha ',
'icon' : 'α'
},
{
'name' : 'beta',
'latex' : '\\beta ',
'icon' : 'β'
},
{
'name' : 'gamma',
'latex' : '\\gamma ',
'icon' : 'γ'
},
{
'name' : 'delta',
'latex' : '\\delta ',
'icon' : 'δ'
},
{
'name' : 'epsilon',
'latex' : '\\epsilon ',
'icon' : 'ε'
},
{
'name' : 'zeta',
'latex' : '\\zeta ',
'icon' : 'ζ'
},
{
'name' : 'eta',
'latex' : '\\eta ',
'icon' : 'η'
},
{
'name' : 'theta',
'latex' : '\\theta ',
'icon' : 'θ'
},
{
'name' : 'iota',
'latex' : '\\iota ',
'icon' : 'ι'
},
{
'name' : 'kappa',
'latex' : '\\kappa ',
'icon' : 'κ'
},
{
'name' : 'lambda',
'latex' : '\\lambda ',
'icon' : 'λ'
},
{
'name' : 'mu',
'latex' : '\\mu ',
'icon' : 'μ'
},
{
'name' : 'nu',
'latex' : '\\nu ',
'icon' : 'ν'
},
{
'name' : 'xi',
'latex' : '\\xi ',
'icon' : 'ξ'
},
{
'name' : 'pi',
'latex' : '\\pi ',
'icon' : 'π'
},
{
'name' : 'rho',
'latex' : '\\rho ',
'icon' : 'ρ'
},
{
'name' : 'sigma',
'latex' : '\\sigma ',
'icon' : 'σ'
},
{
'name' : 'tau',
'latex' : '\\tau ',
'icon' : 'τ'
},
{
'name' : 'upsilon',
'latex' : '\\upsilon ',
'icon' : 'υ'
},
{
'name' : 'phi',
'latex' : '\\phi ',
'icon' : 'φ'
},
{
'name' : 'chi',
'latex' : '\\chi ',
'icon' : 'χ'
},
{
'name' : 'psi',
'latex' : '\\psi ',
'icon' : 'ψ'
},
{
'name' : 'omega',
'latex' : '\\omega ',
'icon' : 'ω'
}
]
},
{
'name' : 'brackets',
'icon' : '{ }',
'elements' : [
{
'name' : 'parentheses',
'latex' : '\\left( ',
'icon' : '( )',
'inside': '('
},
{
'name' : 'square brackets',
'latex' : '\\left[ ',
'icon' : '[ ]',
'inside': '('
},
{
'name' : 'curly brackets',
'latex' : '\\left{ ',
'icon' : '{ }',
'inside': '('
},
{
'name' : 'chevrons',
'latex' : '\\langle ',
'icon' : '〈 〉',
'inside': '('
},
{
'name' : 'absolute value',
'latex' : '\\left| ',
'icon' : '| |',
'inside': '('
},
{
'name' : 'floor',
'latex' : '\\lfloor \\rfloor',
'icon' : '⌊ ⌋',
'inside': '()'
},
{
'name' : 'ceiling',
'latex' : '\\lceil \\rceil',
'icon' : '⌈ ⌉',
'inside': '()'
}
]
},
{
'name' : 'functions',
'icon' : '<i>f</i>(<i>x</i>)',
'elements' : [
{
'name' : 'sin',
'latex' : '\\sin \\left( ',
'icon' : 'sin',
'inside': '(',
'style': 'small'
},
{
'name' : 'cos',
'latex' : '\\cos \\left( ',
'icon' : 'cos',
'inside': '(',
'style': 'small'
},
{
'name' : 'tan',
'latex' : '\\tan \\left( ',
'icon' : 'tan',
'inside': '(',
'style': 'small'
},
{
'name' : 'arcsin',
'latex' : '\\arcsin \\left( ',
'icon' : 'asin',
'inside': '(',
'style': 'small'
},
{
'name' : 'arccos',
'latex' : '\\arccos \\left( ',
'icon' : 'acos',
'inside': '(',
'style': 'small'
},
{
'name' : 'arctan',
'latex' : '\\arctan \\left( ',
'icon' : 'atan',
'inside': '(',
'style': 'small'
},
{
'name' : 'ln',
'latex' : '\\ln \\left( ',
'icon' : 'ln',
'inside': '(',
'style': 'small'
},
{
'name' : 'lg',
'latex' : '\\lg \\left( ',
'icon' : 'lg',
'inside': '(',
'style': 'small'
},
{
'name' : 'log',
'latex' : '\\log \\left( ',
'icon' : 'log',
'inside': '(',
'style': 'small'
},
{
'name' : 'min',
'latex' : '\\min \\left( ',
'icon' : 'min',
'inside': '(',
'style': 'small'
},
{
'name' : 'max',
'latex' : '\\max \\left( ',
'icon' : 'max',
'inside': '(',
'style': 'small'
}
]
},
{
'name' : 'dots',
'icon' : '...',
'elements' : [
{
'name' : 'dots',
'latex' : '\\dots ',
'icon' : '…'
},
{
'name' : 'cdots',
'latex' : '\\cdots ',
'icon' : '⋯'
},
{
'name' : 'vdots',
'latex' : '\\vdots ',
'icon' : '⋮'
},
{
'name' : 'ddots',
'latex' : '\\ddots ',
'icon' : '⋰'
}
]
},
{
'name' : 'sets',
'icon' : '⊆',
'elements' : [
{
'name' : 'subset',
'latex' : '\\subset ',
'icon' : '⊂'
},
{
'name' : 'supset',
'latex' : '\\supset ',
'icon' : '⊃'
},
{
'name' : 'subseteq',
'latex' : '\\subseteq ',
'icon' : '⊆'
},
{
'name' : 'supseteq',
'latex' : '\\supseteq ',
'icon' : '⊇'
},
{
'name' : 'union',
'latex' : '\\cup ',
'icon' : '∪'
},
{
'name' : 'intersection',
'latex' : '\\cap ',
'icon' : '∩'
}
]
},
{
'name' : 'arrows',
'icon' : '⇑',
'elements' : [
{
'name' : 'leftarrow',
'latex' : '\\leftarrow ',
'icon' : '←'
},
{
'name' : 'rightarrow',
'latex' : '\\rightarrow ',
'icon' : '→'
},
{
'name' : 'uparrow',
'latex' : '\\uparrow ',
'icon' : '↑'
},
{
'name' : 'downarrow',
'latex' : '\\downarrow ',
'icon' : '↓'
},
{
'name' : 'Leftarrow',
'latex' : '\\Leftarrow ',
'icon' : '⇐'
},
{
'name' : 'Rightarrow',
'latex' : '\\Rightarrow ',
'icon' : '⇒'
},
{
'name' : 'Uparrow',
'latex' : '\\Uparrow ',
'icon' : '⇑'
},
{
'name' : 'Downarrow',
'latex' : '\\Downarrow ',
'icon' : '⇓'
},
{
'name' : 'updownarrow',
'latex' : '\\updownarrow ',
'icon' : '↕'
},
{
'name' : 'leftrightarrow',
'latex' : '\\leftrightarrow ',
'icon' : '↔'
},
{
'name' : 'Updownarrow',
'latex' : '\\Updownarrow ',
'icon' : '⇕'
},
{
'name' : 'Leftrightarrow',
'latex' : '\\Leftrightarrow ',
'icon' : '⇔'
},
{
'name' : 'nwarrow',
'latex' : '\\nwarrow ',
'icon' : '↖'
},
{
'name' : 'nearrow',
'latex' : '\\nearrow ',
'icon' : '↗'
},
{
'name' : 'searrow',
'latex' : '\\searrow ',
'icon' : '↘'
},
{
'name' : 'swarrow',
'latex' : '\\swarrow ',
'icon' : '↙'
}
]
}];
})(jQuery)
//}}}
<!--{{{-->
<!-- <div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'> -->
<div class='header' macro='headerslide'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<!--
<div id='mainMenu' macro='menuaction'>
<div id='mainMenuGen' macro='menugen 0 0'></div>
<div id='mainMenuToc' refresh='content' tiddler='BookToc'></div>
</div>
-->
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id="menutoolbar">
<div id='leftmenu' class='toolmenu' refresh='content' tiddler='leftMenu'></div>
<div id='rightmenu' class='toolmenu' refresh='content' tiddler='rightMenu'></div>
</div>
<div id='ebookshadow'></div>
<div id='displayArea'>
<div id='messageWrapper'><div id='messageArea'></div></div>
<div id='pageOneWrapper' class='pageWrapper' pagenumber='0'>
<div id='pageOneNavi' class='pageNavi' refresh='content' tiddler='pageOneNavi'></div>
<div id='pageOne' class='bookpage' refresh='content' tiddler='pageOne'></div>
</div>
<div id='tiddlerDisplay'></div>
<div id='sidePage'>
<div id='pageTwoWrapper' class='pageWrapper' pagenumber='1'>
<div id='pageTwoNavi' class='pageNavi' refresh='content' tiddler='pageTwoNavi'></div>
<div id='pageTwo' class='bookpage' refresh='content' tiddler='pageTwo'></div>
</div>
<div id='sidePageHead' refresh='content' tiddler='SidePageHead'></div>
<div id='sidePageContent' refresh='content' tiddler='SidePageContent'></div>
</div>
<div id='actionButtons' class='buttonbar' macro='actionbuttons'></div>
</div>
<div id='mathpanel' macro='mqpanel'></div>
<div id="footermenutoolbar">
<div id='bottomleftmenu' class='toolmenu' refresh='content' tiddler='bottomleftMenu'></div>
<div id='bottomrightmenu' class='toolmenu' refresh='content' tiddler='bottomrightMenu'></div>
</div>
<!--}}}-->
<<showData>>
<data>{"abc":{"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"a+b","virgin":false}],"relation":[],"motivation":[],"check":""},"moi":{"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"kl+fg","virgin":false},{"text":"1+2","virgin":false}],"relation":[{"text":"=","virgin":false}],"motivation":[{"text":"lasku","subderiv":["moisub1","moisub0"],"virgin":false}],"check":""},"moisub0":{"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"3\\cdot4","virgin":false},{"text":"12","virgin":false}],"relation":[{"text":"=","virgin":false}],"motivation":[{"text":"kertolasku","subderiv":[],"virgin":false}],"check":""},"moikka":{"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"1+2","virgin":false}],"relation":[],"motivation":[],"check":""},"moisub1":{"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"a\\cdot\\left(b+c\\right)","virgin":false},{"text":"ab+ac","virgin":false}],"relation":[{"text":"=","virgin":false}],"motivation":[{"text":"distributiivilaki","subderiv":[],"virgin":false}],"check":""}}</data>
<<showData>>
<data>{"abcc":["abccsub0"],"aaaa":["aaaasub0"]}</data>
//{{{
config.macros.qedderiv2 = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var derivation = new SdDerivation('tiddlywiki');
derivation.open(params[0]);
var editmode = params[1];
var derivtext = derivation.html(editmode);
derivtext = derivtext.replace(/\$([^\$]+)\$/g, '<span class="mathquill-embedded-latex">$1</span>');
var derivTable = '<html>' + derivtext+'</html>';
wikify(derivTable, place);
// if (LMprocessNode && isPluginEnabled(getPluginInfo(store.getTiddler("ASCIIMathMLPlugin")))) {LMprocessNode(place,false);}
jQuery(place).find('.structuredderivation').last()[0].derivation = derivation;
jQuery(place).find('.structuredderivation').last().find('.button.command_qededit').click(function(){
jQuery(this).parents('.structuredderivation')[0].derivation.edit(this);
});
jQuery(place).find('.structuredderivation').last().find('.mathquill-editable').mathquill('editable');
jQuery(place).find('.structuredderivation').last().find('.mathquill-textbox').mathquill('textbox');
jQuery(place).find('.structuredderivation').last().find('.mathquill-embedded-latex').mathquill();
// jQuery('.button.command_qededit.' + params[0]).click(function(){
// sDerivation.edit(params[0], tiddler);
// });
}
}
config.macros.qedderiv = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var extraparams = {};
if (params[1] != 'undefined'){
if (params[1] == 'savehere'){
extraparams['tiddler'] = tiddler.title;
}
}
var editor = new QedEditor(params[0], place, 'tiddlywiki', extraparams);
if (jQuery('#mathbuttonwrapper').length == 0){
jQuery(place).parents('.tiddler, .bookpage').eq(0).append('<div id="mathbuttonwrapper"></div>');
}
editor.show();
jQuery(place).find('.qededitor:not(.qedediting)').last().find('.extramotivation').click(function(){jQuery(this).toggleClass('extrashow')});
/*
if (jQuery(place).parents('.ebookbox').length > 0){
jQuery(place).find('.qededitor').last().before('<div class="sdauthorbuttons"><a href="javascript:;" class="sdauthorbutton_edit">Edit</a><a href="javascript:;" class="sdauthorbutton_send">Send</a></div>')
.prev().find('a.sdauthorbutton_edit').click(function(){
var tool = new Authortool(jQuery(this));
jQuery(this).parent().find('a.sdauthorbutton_send').unbind('click').click(function(){
tool.sendSd();
});
tool.startAuthoring('editsd');
}).button().end()
.find('a.sdauthorbutton_send').button().hide();
}
*/
}
}
QedEditor.options.lang = jQuery('body').attr('lang') || 'fi';
(function(){
var plugins = DataTiddler.getData('editor_plugin_data','plugins',{});
for (var i = 0; i < plugins.length; i++){
var scriptline = jQuery('<script type="text/javascript" src="'+plugins[i].jsurl+'"></script>');
jQuery('body').append(scriptline);
if (typeof(plugins[i].cssurl) != 'undefined'){
var cssline = jQuery('<link rel="stylesheet" type="text/css" href="'+plugins[i].cssurl+'">');
jQuery('head').append(cssline);
}
}
QedEditor.plugindata.plugins = plugins;
})()
//}}}
/***
|''Name:''|SdBookJS|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|SdBook functionalities for TiddlyWiki|
|''Version:''|1.3|
|''Date:''|May 31, 2011|
|''Source:''||
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131009.1018 ''add'' ''Version 1.3''
* translatemark for assignments
>>>
<<<
20131009.1018 ''add'' ''Version 1.3''
* modelsolution add button
<<<
<<<
20130903.1400 ''fix''
* "reset updates" button in settings dialog
<<<
<<<
20130902.1000 ''fix''
* hint and extra language fix
<<<
<<<
20130902.0900 ''fix''
* showSolution shows only own solutions
<<<
!!!!!Code
***/
//{{{
config.macros.teachertoolsmenu= {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if(typeof(Teachertool)=="function"){
var teacherselection = jQuery(place).append('<div class="ebookteachertools hidden">\n <ul class="teacherselection">\n<li class="teacherAdd">'+EbookDictionary.localize('ADD')+'</li>\n<li class="teacherEdit">'+EbookDictionary.localize('edit')+'...</li>\n<li class="teacherHomeassignments">'+EbookDictionary.localize('Home assignments')+'</li>\n<li class="teacherChecksolutions">'+EbookDictionary.localize('Check solutions')+'</li>\n<li class="teacherUseStudentView">'+EbookDictionary.localize('show student view')+'</li>\n</ul></div>').find('.teacherselection');
if(store.tiddlerExists('courseManagement.js')){
teacherselection.append('<li class="studentManagement">'+EbookDictionary.localize('Student management')+'</li>\n</ul></div>');
}
jQuery('.ebookteachertools').click(function(){
var elements = store.reverseLookup('teacherchapter',jQuery('#pageOne > [tiddler]').attr('tiddler'), true, '+created');
var homeassignments =[];
for (var i = 0; i<elements.length; i++){
if(elements[i].data('teacherdata') && elements[i].data('teacherdata')['type'] ==="homeassignments"){
homeassignments.push(elements[i]);
}
}
jQuery(this).find('.teacherHomeassignments ul').remove();
if(homeassignments.length>0){
var sublistHomeassignment = jQuery(this).find('.teacherHomeassignments').append('<ul></ul>').find('ul');
for(var i = 0; i<homeassignments.length; i++){
var thisModified = homeassignments[i].modified.convertToLocalYYYYMMDDHHMM();
var printDate = thisModified.substr(6,2)+'.'+thisModified.substr(4,2)+'.'+thisModified.substr(0,4);
sublistHomeassignment.append('<li class="editHomeassignment" tiddler="'+homeassignments[i].title+'">'+EbookDictionary.localize('edit homeassignments')+' '+printDate+'</li>');
}
sublistHomeassignment.append('<li class="newHomeassignment">'+EbookDictionary.localize('new homeassignments')+'</li>');
jQuery(this).find('.editHomeassignment').click(function(){
var teacher = new Teachertool();
teacher.tiddlerName = jQuery(this).attr('tiddler');
teacher.startAuthoring('markhomeassignments');
jQuery(this).parents('.ebookteachertools').toggleClass('hidden');
return false;
});
}
jQuery(this).toggleClass('hidden');
});
teacherselection.find('.teacherAdd').click(function(){
var teacher = new Teachertool();
teacher.startAuthoring('addelement');
}).end().find('.teacherEdit').click(function(){
var teacher = new Teachertool();
teacher.startAuthoring('edit');
}).end().find('.teacherHomeassignments').click(function(){
if(jQuery('#pageOne').find('.homeassignmentsButtons').length ==0){
var teacher = new Teachertool();
teacher.startAuthoring('markhomeassignments');
}
}).end().find('.teacherChecksolutions').click(function(){
Emathbook.getCourseUpdatesSilent();
}).end().find('.studentManagement').click(function(){
var managementDialog = jQuery('body').append('<div class="studentcontrol"></div>').find('.studentcontrol');
managementDialog.dialog({
modal: true,
height: 500,
width:1000,
resizable: false,
buttons: {
"Close": function() {
jQuery(this).find('#courseStudentsTable').dataTable().fnDestroy();
jQuery( this ).dialog('close').dialog( "destroy" ).remove();
}
}
}).hide();
wikify('<<tiddler courseManagement>>',managementDialog[0]);
jQuery('#getStudentsFromServerButton').click();
managementDialog.show();
}).end().find('.teacherUseStudentView').click(function(){
var teacher = new Teachertool();
teacher.studentView();
});
}
}
}
config.macros.booksettingmenu = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
jQuery(place).append('<div class="booksettingsmenu hidden">\n <ul class="booksettingsselection">\n'
+'<li id="indicatorlights"><ul><li id="onlineindicator" class="indicator"></li><li id="onsyncindicator" class="indicator"></li></ul></li>\n'
+'<li class="checkUpdates">'+EbookDictionary.localize('Check courseupdates')+'</li>\n'
+'<li class="presentationopen">'+EbookDictionary.localize('presentation view open')+'</li>\n'
+'<li class="mqpaneltoggle"><span class="mqpanelvisible">'+EbookDictionary.localize('Show mqpanel')+'</span><span class="mqpanelnonvisible">'+EbookDictionary.localize('Hide mqpanel')+'</span></li>\n'
+'<li class="calculatoropen">'+EbookDictionary.localize('Calculator')+'</li>\n'
+'<li class="ebsettingsmenu">'+EbookDictionary.localize('Ebook Settings')+'</li>\n'
+'<li class="personalnote">'+EbookDictionary.localize('give feedback')+'</li>'
+'<li class="openemathcenter">'+EbookDictionary.localize('openemathcenter')+'<form id="goEmathForm" method="post" action="http://emath.utu.fi/emathcenter/directlogin/direct_login.php" target="_blank"><input type="hidden" name="username" value="'+config.options.txtUserName+'" /><input type="hidden" name="password" value="'+config.options.txtUserKey+'" /></form>'+'</li>'
+'<li class="closebookmenu">'+EbookDictionary.localize('Close book')+'</li>'
+'</ul></div>');
jQuery(place).find('.booksettingsmenu').click(function(){
if (jQuery(this).hasClass('hidden')){
Emathbook.pingServer();
}
jQuery(this).toggleClass('hidden');
});
jQuery(place).find('#onlineindicator').click(function(e){
e.stopPropagation();
Emathbook.pingServer();
});
if(typeof(Authortool)=="function"){
jQuery(place).find('.checkUpdates').remove();
}else{
jQuery(place).find('.checkUpdates').click(function(){
Emathbook.getCourseUpdates();
refreshElements(jQuery('#pageOneWrapper')[0]);
refreshElements(jQuery('#pageTwoWrapper')[0]);
});
}
jQuery(place).find('.presentationopen').click(function(){
var presentation = new EmathSlide();
presentation.start();
});
jQuery(place).find('.mqpaneltoggle').click(function(){
jQuery('body').toggleClass('showmqpanel');
});
jQuery(place).find('.calculatoropen').click(function(){
Emathbook.appopen('calculator');
});
jQuery(place).find('.openemathcenter').click(function(){
jQuery(this).find('#goEmathForm').submit()
});
jQuery(place).find('.personalnote').click(function(){
if (typeof(Authortool) === 'function'){
var commtool = new Authortool();
commtool.pageComment();
} else {
Emathbook.pageComment();
}
});
jQuery(place).find('.ebsettingsmenu').click(function(){
var settingsdialog = jQuery('body').append('<div id="ebsettingsdialog"></div>').find('#ebsettingsdialog');
wikify('<<tiddler EbookSettings>>', settingsdialog[0]);
settingsdialog.dialog({
width: 600,
title: EbookDictionary.localize('Ebook Settings'),
maxHeight: 600,
dialogClass: 'ebsettingsdialog',
closeText: 'OK',
buttons: [
{
id: "fixEbook",
text: EbookDictionary.localize('reset updates'),
click: function(){
if (typeof(Authortool) === 'function'){
var inittype = 'author';
Emathbook.options.user.updates.lastSysCheck = '0';
Emathbook.options.saveUserSettings();
} else {
var inittype = 'course';
Emathbook.options.lastCourseSyscheck = '0';
Emathbook.options.courses[Emathbook.options.pages[0].courseid].lastCheck = '0';
Emathbook.options.saveCourseSettings();
}
Emathbook.initBook(inittype);
jQuery(this).dialog('destroy').remove();
}
},
{
text:EbookDictionary.localize('connect book to coursemanagement'),
id:"settingscoursemanagementswitch",
click: function(){
Emathbook.promptUserName();
jQuery(this).dialog('destroy').remove();
}
},
{
text: 'Ok',
click: function(){jQuery(this).dialog('destroy').remove();}
}
]
});
});
jQuery(place).find('.closebookmenu').click(function(){
var logoimgtext = wikifyStatic('[img[emath-logo-blue.png]]');
var bookclosed = jQuery('<div id="bookclosedwindow"><div id="bookclosingcontent"><h1>'+EbookDictionary.localize('Saving and closing')+'</h1></div><div style="display:none;" id="bookclosecontent"><div class="center">'+logoimgtext+'</div><h1>'+EbookDictionary.localize('Book is closed')+'</h1><a href="javascript:window.location.reload()">'+EbookDictionary.localize('Open book')+'</a></div></div>').appendTo('body');
if(typeof(Authortool) === "function"){
saveChanges();
setTimeout(function(){
jQuery('#bookclosingcontent').hide();
jQuery('#bookclosecontent').slideDown('slow');},2000);
}else{
Emathbook.sendOfflineCourseContent();
}
});
}
}
config.macros.newsolution = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var tiddlername = tiddler.title;
var basename = params[0] || 'solution';
var buttonstext = '{{solutionbuttons{ <html><a href="javascript:;" class="addsolutionsd sdbookbutton"><span>+ Derivation</span></a><span class="sdbookbuttonmid"></span><a href="javascript:;" class="addsolutiontext sdbookbutton"><span>+ Text</span></a></html>}}}';
wikify(buttonstext, place);
var edata = {'basename': basename, 'tiddler': tiddlername};
jQuery('.addsolutionsd:last').click(edata, function(e){
var derdata = DataTiddler.getData(e.data.tiddler, 'derivations', {});
var tiddler = store.getTiddler(e.data.tiddler);
var i = 0;
while (typeof(derdata[e.data.basename+'sd'+i]) != 'undefined' || tiddler.text.match('<<qedderiv '+e.data.basename+'sd'+i)){
i++;
}
var derivname = e.data.basename + 'sd' + i;
tiddler.set(tiddler.title, tiddler.text.replace('<<newsolution>>', '<<qedderiv ' + derivname + ' savehere>>\n<<newsolution>>'));
story.refreshAllTiddlers();
});
jQuery('.addsolutiontext:last').click(edata, function(e){
var textdata = DataTiddler.getData(e.data.tiddler, 'mathtext', {});
var tiddler = store.getTiddler(e.data.tiddler);
var i = 0;
while (typeof(textdata[e.data.basename+'text'+i]) != 'undefined' || tiddler.text.match('<<mathtext '+e.data.basename+'text'+i)){
i++;
}
var textname = e.data.basename + 'text' + i;
tiddler.set(tiddler.title, tiddler.text.replace('<<newsolution>>', '<<mathtext ' + textname + '>>\n<<newsolution>>'));
story.refreshAllTiddlers();
});
}
}
config.macros.solutiontiddler = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var tiddlername = params[0];
var solclassstart = '{{sdbooksolution{\n';
var solclassend = '\n}}}';
var text = solclassstart + '<<tiddler [[' + tiddlername + ']]>>' + solclassend;
var alttext = solclassstart + '[[Write a new solution|' + tiddlername + ']]' + solclassend; // Localization!!!
var result;
if (store.tiddlerExists(tiddlername)){
result = text;
} else {
result = alttext;
}
if (!store.tiddlerExists(tiddlername)){
var newtiddler = store.createTiddler(tiddlername);
newtiddler.set(newtiddler.title, '<<qedderiv solutionsd0 savehere>>\n<<newsolution>>');
store.saveTiddler(tiddlername);
}
wikify(result, place);
}
}
config.macros.mathtext = {
/**********************************************
* Insert Mathquill-textbox. The content will
* be saved in this tiddler with DataTiddler-plugin
* on each focusout.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var textid = params[0];
var solclassstart = '{{sdbooksoltext mathtext_'+textid+'{';
var solclassend = '}}}\n';
var textdata = DataTiddler.getData(tiddler, 'mathtext', {});
var text = textdata[textid] || 'text here';
var result = solclassstart + '<html><span class="mathquill-textbox">'+text+'</span></html>' + solclassend;
wikify(result, place);
var edata = {'tiddler': tiddler.title, 'textid': textid};
jQuery('.mathquill-textbox:not(.mathquill-rendered-math):last').mathquill('textbox').focusout(edata, function(e){
var latex = jQuery(this).mathquill('latex');
var textid = e.data.textid;
var tiddler = e.data.tiddler;
var mathdata = DataTiddler.getData(tiddler, 'mathtext', {});
mathdata[textid] = latex;
DataTiddler.setData(tiddler, 'mathtext', mathdata);
});
}
}
//..................................................
//..................................................
config.macros.assignmentAccordion = {
/**********************************************
* Show listed sd assignments in three accordions by their level.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var page = jQuery(place).parents('.bookpage').attr('id');
var pagenum = (page ? ['pageOne','pageTwo'].indexOf(page) : null);
var accordianElement = 'assignmentAccordion';
var i=0;
var defaultlang = Emathbook.options.pages[pagenum]["defaultlang"];
var pagelang = Emathbook.options.pages[pagenum].lang;
if (store.tiddlerExists(params[0])){
var paramsStart=0;
}else{
if (params.length==1){return false;}
var paramsStart=1;
}
accordianElement = 'assignmentAccordion'+i;
if (paramsStart==1){
$tiddler.append('\n<div class="assignmentLevel'+params[0]+'"><h2></h2><div class="'+accordianElement+'"></div></div>\n');
}else{
$tiddler.append('\n<div class="assignmentLevel0"><h2></h2><div class="'+accordianElement+'"></div></div>\n<div class="assignmentLevel1"><h2></h2><div class="'+accordianElement+'"></div></div>\n<div class="assignmentLevel2"><h2></h2><div class="'+accordianElement+'"></div></div>\n');
}
var edata = {};
for(var i=paramsStart;i<params.length;i++){
var toUseTiddler = params[i];
var tarslationmark = "";
if (pagelang != defaultlang){
if(store.tiddlerExists(params[i]+'_'+pagelang)){
toUseTiddler = params[i]+'_'+pagelang;
}else{
if(typeof(Authortool) === "function"){
//temp translatemark
tarslationmark = '<span class="translationmark">T</span>';
}
}
}
if (typeof(store.getTiddler(toUseTiddler).fields.ebooktitle) != 'undefined'){
var additional_title =': '+ store.getTiddler(toUseTiddler).fields.ebooktitle;
}else{
var additional_title ='';
}
if (additional_title.substring(2,9).toLowerCase()=="tehtävä" || additional_title ==": "){
additional_title="";
}
var level = DataTiddler.getData(toUseTiddler, 'level', 0);
var assnumber ='<span class="assignmentNroPlace"></span>';
var html='<h3 tiddler="'+params[i]+'"><a href="#">'+EbookDictionary.localize("assignmentTexture",pagenum)+' '+assnumber+additional_title+tarslationmark+'</a></h3>\n<div>\n<div tiddler="'+params[i]+'" class="assignment_text assignment_text_'+params[i]+'">\n</div>\n<div tiddler="'+params[i]+'" class="emptySolution assigmentSolution assigmentSolution_'+(params[i])+'"></div>\n</div>\n';
$tiddler.find('.assignmentLevel'+level+' .'+accordianElement).append(html);
$tiddler.find('.assignmentLevel'+level+' .'+accordianElement+' div.assignment_text_'+(params[i])).append('<span class="assignmentId">'+params[i]+'</span>');
}
var levelboxes = $tiddler.find('.assignmentLevel0, .assignmentLevel1, .assignmentLevel2');
levelboxes.each(function(){
if (jQuery(this).find('h3[tiddler]').length == 0){
jQuery(this).remove();
}
});
$tiddler.find('.'+accordianElement).accordion({
collapsible: true,
autoHeight: false,
active:false,
change:function(event,ui){
var assignmentIdspan = ui.newContent.find('.assignment_text .assignmentId');
if(assignmentIdspan.length > 0){
var assignmentId = assignmentIdspan.text();
wikify('<<showAssignment '+assignmentId+'>>',assignmentIdspan.parent()[0]);
if(typeof(Teachertool) === "undefined" && typeof(Authortool) === "undefined"){
//Student
wikify('<<showSolution>>',ui.newContent.find('div.assigmentSolution_'+assignmentId)[0]);
}else if(typeof(config.macros.studentsSolutions) !== "undefined"){
//Teacher
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(assignmentId+'_'+pagelang)){
solutionAnswer = store.getTiddler(assignmentId+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(assignmentId).data('assignmentSolution',"");
}
if(solutionAnswer !==""){
var assignmentSolutionPlace = assignmentIdspan.parent().append('<div class="teacherassignmentSolution"><button><span class="hideTeacherAssignmentSolution">'+EbookDictionary.localize('close')+'</span> <span class="answerString">'+EbookDictionary.localize('answer').substring(0,EbookDictionary.localize('answer').length-2)+'</span></button><div class="assignmentSolution solutionAnswer"></div></div>').find('.assignmentSolution');
wikify(solutionAnswer,assignmentSolutionPlace[0]);
assignmentSolutionPlace.parent('.teacherassignmentSolution').addClass('hidden');
assignmentSolutionPlace.parent().find('button').click(function(){
jQuery(this).parent().toggleClass('hidden');
});
}
// HERE IS PLACE TO MAKE MODELSOLUTION BUTTON
wikify('<<studentsSolutions>>',ui.newContent.find('div.assigmentSolution_'+assignmentId)[0]);
}else if(typeof(Authortool)==="function"){
//author
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(assignmentId+'_'+pagelang)){
solutionAnswer = store.getTiddler(assignmentId+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(assignmentId).data('assignmentSolution',"");
}
if(solutionAnswer !==""){
var assignmentSolutionPlace = assignmentIdspan.parent().append('<div class="assignmentSolution solutionAnswer"></div>').find('.assignmentSolution');
wikify(solutionAnswer,assignmentSolutionPlace[0]);
}
wikify('<<showModelsolution>>',ui.newContent.find('div.assigmentSolution_'+assignmentId)[0]);
}
assignmentIdspan.remove();
}else{
var assignmentId=ui.newContent.find('.assignment_text').attr('tiddler');
}
}
});
var bookpageElem = $tiddler.parents('.bookpage').eq(0);
var bookpageNro = pagenum || 0;
if (bookpageElem.attr('id') ==="pageTwo" && $tiddler.parents('.ebookopening').length > 0){
bookpageNro = 0;
}
var currpage = EbookPages[bookpageNro].currentpage;
if ($tiddler.parents('ebookopening').length > 0){
currpage = EbookPages[bookpageNro].ebook.tocdict[currpage].next;
}
var sectionNro = EbookPages[bookpageNro].ebook.getNumberedTitle(currpage).split('.')
var nroPlaces = bookpageElem.find('.sdbookassignmentlist span.assignmentNroPlace');
var teachersnroPlaces = bookpageElem.find('.teacherAccordions span.assignmentNroPlace');
for (var i=0;i<nroPlaces.length;i++){nroPlaces.eq(i).append(sectionNro[0]+'.'+sectionNro[1]+'.'+(i+1));}
for (var i=0;i<teachersnroPlaces.length;i++){teachersnroPlaces.eq(i).append((i+1));}
}
}
config.macros.showSolution = {
/**********************************************
* Show listed sd assignments in three accordions by their level.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var assignmentTiddler = jQuery(place).attr('tiddler');
var possiblesolutions = store.reverseLookup('solutionto',assignmentTiddler, true, 'created');
var solutions = [];
for (var i=0;i<possiblesolutions.length;i++){
if (!possiblesolutions[i].data('solution') || possiblesolutions[i].data('solution').creator.toLowerCase() === config.options.txtUserName.toLowerCase()){
solutions.push(possiblesolutions[i]);
}
}
if(solutions.length == 0){
jQuery(place).append('<button class="startSolution">'+EbookDictionary.localize('Make solution')+'</button>')
.find('.startSolution').click(function(){
var solutionTiddlerName =Emathbook.options.pages[0].courseid+"_"+config.options.txtUserName+"_offline_solution_";
var i=0;
while(store.tiddlerExists(solutionTiddlerName+i)){i++;}
solutionTiddlerName += i;
var solutionTiddler = store.createTiddler(solutionTiddlerName);
solutionTiddler.set(solutionTiddlerName,'<<ebooksolution>>',null,null,['solutiondata','offlinesolution'],null,{"solutionto":assignmentTiddler});
jQuery('h3[tiddler="'+assignmentTiddler+'"] .assignmentNroPlace').after('<span class="solutionsAmount"> (<span class="evaluatedSolutions">0</span> / <span class="createdSolutions">1</span>) </span>');
wikify('<<showSolution>>', jQuery(this).parent()[0], tiddler);
jQuery(this).remove();
}).button();
}else{
var soltabs = jQuery('<div class="solutiontabs"><ul class="solutiontablist"></ul></div>');
var sollist = soltabs.find('ul.solutiontablist');
var solcontent = jQuery('<div class="solutioncontent"></div>');
var hasnonEditable = false;
for (var i = 0; i < solutions.length; i++){
var classes = [];
if (solutions[i].data('solution', {"editable":true}).editable){
classes.push('editable');
}else{
hasnonEditable = true;
}
sollist.append('<li tiddler="'+solutions[i].title+'" class="'+classes.join(' ')+'"><a href="javascript:;">'+(i+1)+'</a></li>');
}
sollist.find('li').last().addClass('currenttab');
sollist.find('li a').click(function(){
var tablist = jQuery(this).parents('ul.solutiontablist');
var contentplace = jQuery(this).parents('.solutiontabs').next();
var solutiontiddler = jQuery(this).parents('li').attr('tiddler');
tablist.find('li').removeClass('currenttab');
jQuery(this).parents('li').addClass('currenttab');
contentplace.empty();
wikify('<<tiddler [['+solutiontiddler+']]>>', contentplace[0], null, tiddler);
var markingtiddler = store.reverseLookup('markingsto',solutiontiddler, true);
if (markingtiddler.length > 0){
markingtiddler = markingtiddler[0].title;
var markings = new SdMarkings({"tiddler":markingtiddler});
markings.read();
markings.show();
}
});
jQuery(place).append(soltabs).append(solcontent);
//wikify('<<tiddler '+solutions[solutions.length-1].title+'>>',solcontent[0]);
sollist.find('li a').last().click();
if(hasnonEditable){
var pageId = jQuery(place).parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
var defaultlang = Emathbook.options.pages[pageNro]["defaultlang"];
var pagelang = Emathbook.options.pages[pageNro].lang;
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(assignmentTiddler+'_'+pagelang)){
solutionAnswer = store.getTiddler(assignmentTiddler+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(assignmentTiddler).data('assignmentSolution',"");
}
if(solutionAnswer !=="" && jQuery(place).parent().find('.assignmentSolution.solutionAnswer').length === 0){
var assignmentSolutionPlace = jQuery(place).parent().append('<div class="assignmentSolution solutionAnswer"></div>').find('.assignmentSolution');
wikify(solutionAnswer,assignmentSolutionPlace[0]);
}
}
}
}
}
config.macros.showAssignment = {
/**********************************************
* Show listed assignments in three accordions by their level.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var pre_qustion_html="";
var post_qustion_html="";
var assignmentTiddler = params[0];
var langinuse = "error";
var pageId = $tiddler.parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
if(Emathbook.options){
if (Emathbook.options.pages[pageNro].lang != Emathbook.options.pages[pageNro]["defaultlang"]){
if(store.tiddlerExists(params[0]+'_'+Emathbook.options.pages[pageNro].lang)){
//Tähän myös lang
assignmentTiddler = params[0]+'_'+Emathbook.options.pages[pageNro].lang;
langinuse = Emathbook.options.pages[pageNro].lang;
}else{
pre_qustion_html = '{{notTranslated{\n';
post_qustion_html = '\n}}}';
langinuse = Emathbook.options.pages[pageNro]["defaultlang"];
}
}else{
langinuse = Emathbook.options.pages[pageNro].lang;
}
}
if (store.tiddlerExists(assignmentTiddler)){
var assignmentData = DataTiddler.getDataObject(assignmentTiddler);
var assignmentType = assignmentData['assignmentType'];
var qustion_html="";
var solutions = store.reverseLookup('solutionto',assignmentTiddler, true);
var lastSolution = ((solutions.length > 0)? solutions[solutions.length-1] : false);
switch(parseInt(assignmentType))
{
case 0:
qustion_html="{{question_text sdquestion{<<tiddler [["+assignmentTiddler+"]]>>}}}";
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
break;
case 1:
qustion_html="{{question_text plaintext{<<tiddler [["+assignmentTiddler+"]]>>}}}";
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
break;
case 2:
qustion_html="{{question_text multichoise{<<tiddler [["+assignmentTiddler+"]]>>}}}";
var choises=[];
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
$tiddler.find('[tiddler="'+assignmentTiddler+'"]').after('<ul class="multichoiseChoises multi'+assignmentTiddler+'"></ul>');
if (lastSolution){
var clicked=DataTiddler.getDataObject(lastSolution);
}else{
var clicked={};
}
choises.push('<li class="choise_1"><span class="multimark">'+((typeof(clicked['choise_1'])=='undefined') ? '<input type="radio" name="'+assignmentTiddler+'" value="choise_1">' : '<span class="multicorrect"><span>✓</span></span>')+'</span><span class="choiseText"></span></li>');
for (var i=0;i<assignmentData['wrong'].length;i++){
choises.push('<li class="choise_'+(i+2)+'"><span class="multimark">'+((typeof(clicked['choise_'+(i+2)])=='undefined') ? '<input type="radio" name="'+assignmentTiddler+'" value="choise_'+(i+2)+'">':'<span class="multiwrong"><span>✗</span></span>')+'</span><span class="choiseText"></span></li>');
}
var $multichoiseList = $tiddler.find('.multichoiseChoises.multi'+assignmentTiddler);
choises.sort(function(a,b){return (Math.random()-0.5)});
choises.sort(function(a,b){return (Math.random()-0.5)});
for(var i=0;i<choises.length;i++){
$multichoiseList.append(choises[i]);
}
wikify(assignmentData['correct'],$multichoiseList.find('li.choise_1 span.choiseText')[0]);
$multichoiseList.addClass((typeof(clicked['choise_1'])=='undefined' ? '':'solved'));
for (var i=0;i<assignmentData['wrong'].length;i++){
wikify(assignmentData['wrong'][i],$multichoiseList.find('li.choise_'+(i+2)+' span.choiseText')[0]);
}
if (!$multichoiseList.hasClass('solved')){
$multichoiseList.find('input[type="radio"]').click(function(){
var $inputElem = jQuery(this);
if (!lastSolution){
lastSolution = store.getTiddler(Emathbook.createSolution(assignmentTiddler,""));
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(lastSolution,$inputElem.val(),"clicked");
if($inputElem.val()=='choise_1'){
$inputElem.after('<span class="multicorrect"><span>✓</span></span>');
$multichoiseList.addClass('solved');
DataTiddler.setData(lastSolution,"multichoise","solved");
}else{
$inputElem.after('<span class="multiwrong"><span>✗</span></span>');
}
$inputElem.remove();
config.options.chkAutoSave = autosaveoption;
});
}
break;
case 3:
qustion_html = "{{question_text shortanswer{<<tiddler [["+assignmentTiddler+"]]>>}}}";
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
$tiddler.find('.mathquill-embedded-latex.mathquill-rendered-math').attr('title','');
var isSolved = 'not';
var editables = $tiddler.find('[tiddler="'+assignmentTiddler+'"] span.solution .mathquill-editable');
var answers = [];
var correctAnswers = DataTiddler.getData(assignmentTiddler,"correct","");
if(lastSolution){
isSolved = DataTiddler.getData(lastSolution,'solved','not');
answers = DataTiddler.getData(lastSolution,'answers',[]);
}else{
for(var i=0;i<editables.length;i++){
answers.push("");
}
}
for(var i=0;i<editables.length;i++){
if (answers[i] != ""){
editables.eq(i).mathquill('latex',answers[i]);
}
}
if (isSolved == "solved"){
editables.removeClass('mathquill-editable');
$tiddler.append('<span class="shortanswercorrect"><span>✓</span></span>');
}else{
editables.focusout(function(){
if(!lastSolution){
lastSolution = store.getTiddler(Emathbook.createSolution(assignmentTiddler,""));
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var thisElement = jQuery(this);
answers[editables.index(thisElement)]=thisElement.mathquill('latex');
DataTiddler.setData(lastSolution,'answers',answers);
if(!!answers && !!correctAnswers && !(answers<correctAnswers || correctAnswers<answers)){
DataTiddler.setData(lastSolution,'solved','solved');
editables.removeClass('mathquill-editable');
$tiddler.append('<span class="shortanswercorrect"><span>✓</span></span>');
editables.unbind('focusout');
}
config.options.chkAutoSave = autosaveoption;
});
}
break;
case 5:
var questionTitle = store.getTiddler(assignmentTiddler).fields.ebooktitle;
qustion_html="!"+((typeof(questionTitle) != "undefined" && questionTitle != "")? questionTitle : EbookDictionary.localize('ordersd',pageNro))+"\n{{question_text sdshuffle{<<tiddler [["+assignmentTiddler+"]]>>}}}";//Localization for header!!
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
if(lastSolution){
$tiddler.addClass('sdInOrder');
}else{
var tableRows = $tiddler.find('.sdtable tr');
for (var i=0;i<tableRows.length;i++){
tableRows.eq(i).attr('order',i);
}
var allDerivations = $tiddler.find('.sdtable').children('tbody');
allDerivations.addClass(assignmentTiddler+'shuffle');
for(var i=0;i<allDerivations.length;i++){
allDerivations.eq(i).children('tr').shuffle();
allDerivations.eq(i).sortable().disableSelection();
}
$tiddler.find('.'+assignmentTiddler+'shuffle').bind( "sortupdate", function(event, ui) {
tableRows = $tiddler.find('.sdtable tr');
for(var i=0;i<tableRows.length;i++){
if(tableRows.eq(i).attr('order') != i){break};
if(i==tableRows.length-1){
$tiddler.find('.'+assignmentTiddler+'shuffle').sortable('destroy');
$tiddler.addClass('sdInOrder');
lastSolution=Emathbook.createSolution(assignmentTiddler,"");
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(lastSolution,'solved','solved');
config.options.chkAutoSave = autosaveoption;
}
}
});
}
break;
case 6:
var questionTitle = store.getTiddler(assignmentTiddler).fields.ebooktitle;
qustion_html="!"+((typeof(questionTitle) != "undefined" && questionTitle != "")? questionTitle : EbookDictionary.localize('fillsd',pageNro))+"\n{{question_text sdfill{<<tiddler [["+assignmentTiddler+"]]>>}}}";//Localization for header!!
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
var fillMotivations = $tiddler.find('[tiddler="'+assignmentTiddler+'"] table.sdtable td.motivation span.solution').addClass('fillMot').mathquill('textbox');
var fillTerms = $tiddler.find('[tiddler="'+assignmentTiddler+'"] table.sdtable td.term span.solution').addClass('fillTerm').mathquill('editable');
var fillRelations = $tiddler.find('[tiddler="'+assignmentTiddler+'"] table.sdtable td.relation span.solution').addClass('fillRelation').mathquill('editable');
var isSolved = 'not';
var editables = jQuery.merge(fillMotivations,fillTerms);
editables = jQuery.merge(editables,fillRelations);
var answers = [];
var correctAnswers = DataTiddler.getData(assignmentTiddler,"correct","");
if(lastSolution){
isSolved = DataTiddler.getData(lastSolution,'solved','not');
answers = DataTiddler.getData(lastSolution,'answers',[]);
}else{
for(var i=0;i<editables.length;i++){
answers.push("");
}
}
for(var i=0;i<editables.length;i++){
if (answers[i] != ""){
editables.eq(i).mathquill('latex',answers[i]);
}
}
if (isSolved == "solved"){
editables.removeClass('mathquill-editable');
$tiddler.addClass('issolved');
}else{
editables.focusout(function(){
if(!lastSolution){
lastSolution = store.getTiddler(Emathbook.createSolution(assignmentTiddler,""));
}
var thisElement = jQuery(this);
answers[editables.index(thisElement)]=thisElement.mathquill('latex');
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(lastSolution,'answers',answers);
if(!!answers && !!correctAnswers && !(answers<correctAnswers || correctAnswers<answers)){
DataTiddler.setData(lastSolution,'solved','solved');
$tiddler.addClass('issolved');
editables.removeClass('mathquill-editable');
editables.unbind('focusout');
}
config.options.chkAutoSave = autosaveoption;
});
}
break;
case 7:
var questionTitle = store.getTiddler(assignmentTiddler).fields.ebooktitle;
qustion_html="!"+((typeof(questionTitle) != "undefined" && questionTitle != "")? questionTitle : EbookDictionary.localize('tablefill',pageNro))+"\n{{question_text tablefill{<<tiddler [["+assignmentTiddler+"]]>>}}}";//Localization for header!!
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
$tiddler.find('.mathquill-embedded-latex.mathquill-rendered-math').attr('title','');
var isSolved = 'not';
var editables = $tiddler.find('[tiddler="'+assignmentTiddler+'"] span.solution .mathquill-editable');
var answers = [];
var correctAnswers = DataTiddler.getData(assignmentTiddler,"correct","");
if(lastSolution){
isSolved = DataTiddler.getData(lastSolution,'solved','not');
answers = DataTiddler.getData(lastSolution,'answers',[]);
}else{
for(var i=0;i<editables.length;i++){
answers.push("");
}
}
for(var i=0;i<editables.length;i++){
if (answers[i] != ""){
editables.eq(i).mathquill('latex',answers[i]);
}
}
if (isSolved == "solved"){
editables.removeClass('mathquill-editable');
$tiddler.addClass('issolved');
}else{
editables.focusout(function(){
if(!lastSolution){
lastSolution = store.getTiddler(Emathbook.createSolution(assignmentTiddler,""));
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var thisElement = jQuery(this);
answers[editables.index(thisElement)]=thisElement.mathquill('latex');
DataTiddler.setData(lastSolution,'answers',answers);
if(!!answers && !!correctAnswers && !(answers<correctAnswers || correctAnswers<answers)){
DataTiddler.setData(lastSolution,'solved','solved');
editables.removeClass('mathquill-editable');
$tiddler.addClass('issolved');
editables.unbind('focusout');
}
config.options.chkAutoSave = autosaveoption;
});
}
break;
case 8:
if (lastSolution){
var quizSolution=DataTiddler.getDataObject(lastSolution);
}else{
var quizSolution={};
}
if(!quizSolution.save){
quizSolution.save={};
quizSolution.save.correct=0;
quizSolution.save.total=0;
}
qustion_html="{{question_text emathQuizassignment{<<emathquiz [["+assignmentData['openQuiz']+"##"+langinuse+"]] [["+quizSolution.save.correct+"##"+quizSolution.save.total+"]] [["+assignmentData['callFunction'].join(']] [[')+"]]>>}}}";
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
jQuery(place).find('.emathQuizassignment').attr('tiddler',assignmentTiddler);
jQuery(place).find('.emathquiz-place').bind('changed', function(e){
if(!lastSolution){
lastSolution = store.getTiddler(Emathbook.createSolution(assignmentTiddler,""));
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var save = jQuery(this).emathquiz('score');
DataTiddler.setData(lastSolution,'save',save);
config.options.chkAutoSave = autosaveoption;
});
break;
default:
qustion_html="{{question_text notTypedquestion{<<tiddler [["+assignmentTiddler+"]]>>}}}";
wikify(pre_qustion_html + qustion_html + post_qustion_html,$tiddler.get(0),false,store.getTiddler(assignmentTiddler));
break;
}
}
}
}
config.macros.otherassignmentAccordion = {
/**********************************************
* Show listed assignments in three accordions by their level.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var otherassignmentTiddler = "";
var translate_html = '';
var page = jQuery(place).parents('.bookpage').attr('id');
var pagenum = (page ? ['pageOne','pageTwo'].indexOf(page) : null);
var accordianElement = 'otherassignmentAccordion';
$tiddler.append('\n<div class="simpleassignments"><h2>'+EbookDictionary.localize("basicAssignmentText", pagenum)+'</h2><div class="'+accordianElement+'"></div>\n</div>\n');//Localization
for(var i=0;i<params.length;i++){
otherassignmentTiddler = params[i];
translate_html = '';
if(Emathbook.options){
if (Emathbook.options.pages[pagenum].lang != Emathbook.options.pages[pagenum]["defaultlang"]){
if(store.tiddlerExists(params[i]+'_'+Emathbook.options.pages[pagenum].lang)){
//Tähän myös lang
otherassignmentTiddler = params[i]+'_'+Emathbook.options.pages[pagenum].lang;
}else{
translate_html = ' class="notTranslated" ';
}
}
}
if (typeof(store.getTiddler(otherassignmentTiddler).fields.ebooktitle) != 'undefined'){
if (store.getTiddler(otherassignmentTiddler).fields.ebooktitle != ''){
var additional_title =': '+ store.getTiddler(otherassignmentTiddler).fields.ebooktitle;
}else{
var additional_title ='';
}
}else{
var additional_title ='';
}
// var assnumber = $tiddler.find('.'+accordianElement+' h3[tiddler]').length + 1;
var assnumber ='<span class="assignmentNroPlace"></span>';
var html='<h3 tiddler="'+otherassignmentTiddler+'"'+translate_html+'><a href="#">'+EbookDictionary.localize("assignmentTexture", pagenum)+' '+assnumber+additional_title+'</a></h3>\n<div>\n<div class="assignment_text assignment_text_'+otherassignmentTiddler+'"></div>\n</div>\n';//Localization
$tiddler.find('.'+accordianElement).append(html);
wikify(store.getTiddler(otherassignmentTiddler).text,$tiddler.find('.'+accordianElement+' div.assignment_text_'+(otherassignmentTiddler)).get(0),false,store.getTiddler(otherassignmentTiddler));
}
var otherassignmentbox = $tiddler.find('.otherassignmentAccordion');
if (otherassignmentbox.find('h3[tiddler]').length == 0){
jQuery(place).parents('.bookpage').find('.simpleassignments').remove();
}
$tiddler.find('.otherassignmentAccordion').accordion({
collapsible: true,
autoHeight: false,
active:false
});
}
}
config.macros.ebookbox = {
/**********************************************
* Insert an ebookbox. Several types as:
* - example
* - theory
* - assignment
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var pageId = $tiddler.parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
var defaultlang = Emathbook.options.pages[pageNro]["defaultlang"];
var pagelang = $tiddler.attr('pagelang') ||$tiddler.parents('[pagelang]').attr('pagelang') || Emathbook.options.pages[pageNro].lang;
var langinuse = pagelang;
var extradiv="";
var target = '';
var boxclassstart = '';
var boxclassend = '';
var tiddlername = params[0];
if(Emathbook.options){
if (jQuery(place).parents('.ebookopening').length > 0){
var pageNro = 0;
}
if (pagelang != defaultlang){
if(store.tiddlerExists(params[0]+'_'+pagelang)){
tiddlername = params[0]+'_'+pagelang;
if(store.getTiddler(params[0]).modified > store.getTiddler(tiddlername).modified){
boxclassstart = '{{CheckTranslation{\n';
boxclassend = '\n}}}';
extradiv = ' > div.CheckTranslation ';
}
}else{
langinuse = defaultlang;
boxclassstart = '{{notTranslated{\n';
boxclassend = '\n}}}';
extradiv = ' > div.notTranslated ';
}
}
if(params[1] ==="assignmentlist"){langinuse = pagelang;}//FIXING assignmentlist languageBug
}
if (params[1]){
target = params[1];
if(target=="assignmentlist"){
boxclassstart = '';
boxclassend = '';
extradiv = '';
}
boxclassstart += '{{sdbook'+params[1]+' '+(tiddler.fields.extraclass||"")+'{\n';
boxclassend += '\n}}}';
}
var text = '{{ebookbox{\n' +
boxclassstart+'<<tiddler [[' + tiddlername + ']]>>\n' + boxclassend +
'}}}';
var alttext = boxclassstart+'[[' + tiddlername + ']]'+boxclassend;
if (store.tiddlerExists(tiddlername)){
wikify(text, place);
$tiddler = $tiddler.find('.ebookbox').last();
jQuery(place).find('.ebookbox').attr('lang', langinuse );
var parenttiddler = tiddler.title;
var subelements = [['hint','prepend'],['extra','append']];
for(var i=0;i<subelements.length;i++){
if (store.tiddlerExists(parenttiddler+'_'+subelements[i][0])){
var subelementtiddler = parenttiddler+'_'+subelements[i][0];
var addedclass = "";
if (pagelang != defaultlang){
if (store.tiddlerExists(parenttiddler+'_'+subelements[i][0]+'_'+pagelang)){
subelementtiddler += "_"+pagelang;
if(store.getTiddler(parenttiddler+'_'+subelements[i][0]).modified > store.getTiddler(subelementtiddler).modified && typeof(Authortool) =="function"){
addedclass = " CheckTranslation";
}
}else{
addedclass = " notTranslatedextra";
}
}
var subelementplace = jQuery('<div tiddler="'+subelementtiddler+'" class="ebwrapper'+addedclass+'"></div>');
jQuery(place).find('.ebookbox'+extradiv+' > div').last()[subelements[i][1]](subelementplace);
var hintbox = new EbExtrabox(subelements[i][0], subelementtiddler, subelementplace);
hintbox.showIcon();
}
}
} else {
wikify(alttext, place);
};
}
}
config.macros.ebooktable = {
/**********************************************
* marcro for tables
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 2) {
wikify("{{sdalert{ebooktable: missing some arguments}}}", place, null, tiddler);
return false;
}
var savehere = false;
var tiddlerName = params[0];
var boxclassstart = '';
var boxclassend = '';
var $tiddler = jQuery(place);
var pageId = $tiddler.parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
if(Emathbook.options && !(params[2] == 'savehere')){
if (Emathbook.options.pages[pageNro].lang != Emathbook.options.pages[pageNro]["defaultlang"]){
if(store.tiddlerExists(params[0]+'_'+Emathbook.options.pages[pageNro].lang)){
//Tähän myös lang
tiddlerName = params[0]+'_'+Emathbook.options.pages[pageNro].lang;
}else{
boxclassstart = '{{notTranslated{\n';
boxclassend = '\n}}}';
}
}
}
var tableName = 'table0';
if (params.length == 3 && params[2] == 'savehere'){
savehere = true;
tableName = tiddlerName;
tiddlerName = jQuery(place).attr('tiddler') || jQuery(place).parents('[tiddler]').attr('tiddler');
if(tiddlerName.indexOf('ebook_assignmentlist') != -1){tiddlerName=jQuery(place).parent().prev().attr('tiddler');}
}
var tableClass = params[1];
if (tableClass == 'casetable'){
testilogit.place = place;
jQuery(place).find('span.eblinebreak').last().remove();
jQuery(place).append('<div class="casewrapper"><div class="casebracket">{</div></div>');
place = jQuery(place).find('.casewrapper').last()[0];
}
if (store.tiddlerExists(tiddlerName)) {
var alltabledata = DataTiddler.getData(tiddlerName, "table", {"table0": {"rows": 1, "cols":1, "data":[[""]], "caption": ""}});
var tabledata = alltabledata[tableName];
var wikitext = "|" + tableClass + "|k\n";
for (var i = 0; i < tabledata.data.length; i++) {
for (var j = 0; j < tabledata.data[i].length; j++){
wikitext += "|";
wikitext += (tabledata.types[i][j] == 'math' ? '\\('+tabledata.data[i][j]+'\\)':tabledata.data[i][j]);
}
wikitext += '|\n';
// wikitext += "|" + tabledata.data[i].join("|") + "|\n";
}
if (tabledata.caption != ''){
wikitext += '|'+tabledata.caption+'|c'
// wikitext += '{{tablecaption{\n'+tabledata.caption+'}}}'
}
wikify(boxclassstart + wikitext + boxclassend, place, null, tiddler);
} else {
wikify("{{sdalert{ebooktable: missing tiddler " + tiddlerName + "}}}", place, null, tiddler);
return false;
}
if (tableClass == 'casetable'){
var cwrapper = jQuery(place);
var origheight = jQuery(place).find('.casebracket').height();
var cheight = cwrapper.height();
var hscale = cheight / origheight;
cwrapper.parent().find('.casewrapper .casebracket').last()
.css('-moz-transform', 'scale(1.7,'+hscale+')')
.css('-webkit-transform', 'scale(1.7,'+hscale+')')
.css('-o-transform', 'scale(1.7,'+hscale+')')
.css('-ms-transform', 'scale(1.7,'+hscale+')')
.css('transform', 'scale(1.5,'+hscale+')');
}
}
}
config.macros.ebooknumberline = {
/**********************************************
* marcro for numberline
**********************************************/
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('{{sdalert{ebooknumberline: Missing numberline name.}}}',place);
return false;
}
var savehere = false;
var tiddlerName = params[0];
var nlineName = 'nline0';
if (params.length == 2 && params[1] == 'savehere'){
savehere = true;
nlineName = tiddlerName;
tiddlerName = tiddler.title;
}
if (store.tiddlerExists(tiddlerName)){
var allnlinedata = DataTiddler.getData(tiddlerName, "nline", {"nline0": {"startval": -10, "endval": 10, "points":[], "text": ""}});
var nlinedata = allnlinedata[nlineName];
var nline = new EmathbookNumberline();
nline.init(nlinedata.startval, nlinedata.endval);
for (var name in nlinedata.points){
nline.addPoint(name, nlinedata.points[name].xcoord, nlinedata.points[name].color, nlinedata.points[name].fillcolor, nlinedata.points[name].face, nlinedata.points[name].ptype);
}
for (var name in nlinedata.ranges){
nline.addRange(name, nlinedata.ranges[name].from, nlinedata.ranges[name].to, nlinedata.ranges[name].color, nlinedata.ranges[name].rtype);
}
wikify('{{emathbooknumberlinecontainer{\n}}}{{emathbooknumberlinecaption{'+nlinedata.text+'}}}', place);
nline.create(jQuery(place).find('.emathbooknumberlinecontainer:last')[0]);
} else {
wikify("{{sdalert{ebooknumberline: missing tiddler " + tiddlerName + "}}}", place);
return false;
}
}
}
config.macros.hiddableExample = {
/**********************************************
* Make some content of example hiddable.
* Hiddable content is marked with .sdbookhidden -class.
* Content is shown/hidden by clicking the h1-header of the box.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $hidden = jQuery(place);
$hidden.parents('.sdbookexample').eq(0).addClass('sdclickable').find('h1').click(function(){
jQuery(this).parents('.sdbookexample').find('.sdbookhidden').toggle('slow');
});
}
};
var Eapp;
config.macros.sdexercise = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var exclabel = {'en': 'Exercise', 'fi': 'Harjoitus', 'sv': 'Övning'};
wikify('{{sdbuttonexercise '+params[0]+'{{{sdbuttonlabel{'+params[1]+'}}} {{exclabel{'+exclabel[QedEditor.options.lang]+'}}} }}}', place);
jQuery('.sdbuttonexercise.'+params[0]).click(function(){
switch (params[0]){
case 'roman':
sdRoman.Init();
break;
case 'fracCalc':
Eapp = new EbookApp();
Eapp.initGame('fracCalc');
default:
break;
}
});
}
}
config.macros.mathgraph = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){ return false; }
if (typeof(params[1]) != 'undefined'){
var width = params[1] + 'px';
} else {
var width = '400px';
}
if (typeof(params[2]) != 'undefined'){
var height = params[2] + 'px';
} else {
var height = width;
}
var scripttiddlername = params[0];
var scripttiddler = store.getTiddler(scripttiddlername);
var script = scripttiddler.text;
var elementid = scripttiddlername.split(':').pop();
var i = 0;
while (jQuery('#'+elementid+i).length > 0){
i++;
}
elementid = elementid + i;
var wikitext = '<html><div id="'+elementid+'" class="jxgbox" style="width:'+width+';height:'+height+'; magin-left: auto; margin-right: auto;"></div></html>';
wikify(wikitext, place);
eval(script);
drawgraph(elementid);
}
}
config.macros.youtubevideo = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){return false;}
var videourl = params[0];
if (!videourl.match(/^http[s]?:\/\//)){
videourl = 'https://www.youtube.com/embed/' + videourl;
}
var wikitext = '<html><iframe width="560" height="315" src="'+videourl+'?rel=0" frameborder="0" allowfullscreen></iframe></html>';
wikify(wikitext, place);
}
}
config.macros.theoryshuffle = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
function correct_order(element){
element.find('.skip_button').hide();
element.find('.question_box ul').animate({
marginLeft: '20px'
},1000,function(){
element.find('li.ui-state-default').removeClass('ui-state-default');
element.find('li.ui-state-highlight').removeClass('ui-state-highlight');
element.find('.theory_shuffle').addClass('sdbooktheory');
element.find('.theory_shuffle_header').slideDown('slow',
function(){
element.find('.theory_shuffle_add').show('slow',function(){
element.find('.theory_shuffle_text').slideDown('slow');
element.find('.refresh_button').show();
});
});
});
}
var $element = jQuery(place);
if (params.length < 1){ return false; }
var tiddlername = params[0];
var wikitext = '<<tiddler [['+tiddlername+']]>>\n';
wikify(wikitext, place);
var ul_elements = $element.find('ul');
var li_elements=$element.find('li');
var max_height=0;
for (var i =0;i<li_elements.length;i++){
if (li_elements.eq(i).height() > max_height){max_height=li_elements.eq(i).height();}
};
li_elements.css('height',max_height+'px').css('line-height',max_height+'px');
ul_elements.eq(0).find('li').addClass('ui-state-default');
ul_elements.eq(1).find('li').addClass('ui-state-highlight').append('<span class="block_mathquill_insert"></span>');
var original_order = ul_elements.eq(1).clone();
var orig_lis=ul_elements.eq(1).find('li');
while(ul_elements.eq(1).html().replace(/\s*/g,'')==original_order.html().replace(/\s*/g,'')){
orig_lis.sort(function (){return Math.round(Math.random())-0.5;}).appendTo(ul_elements.eq(1));
}
ul_elements.eq(1).sortable({
update:function()
{
if (jQuery(this).html().replace(/\s*/g,'').replace(/position:relative;left:0px;top:0px;/g,'')==original_order.html().replace(/\s*/g,'')){
jQuery(this).sortable({disabled:true});
correct_order($element);
}
}
}).disableSelection();
$element.append('<button class="skip_button">Skip</button>');//localize
$element.append('<button class="refresh_button">Refresh</button>');//localize
$element.find('.refresh_button').hide();
$element.find('.skip_button').button({
icons: {
secondary: "ui-icon-seek-end"
}
}).click(function(){
ul_elements.eq(1).html(original_order.html());
correct_order($element);
ul_elements.eq(1).sortable({disabled:true});
jQuery(this).hide();
});
$element.find('.refresh_button').button({
icons: {
secondary: "ui-icon-refresh"
}
}).click(function(){
$element.find('.question_box ul').css('margin-left','200px');
$element.find('.theory_shuffle_header, .theory_shuffle_add, .theory_shuffle_text').hide();
ul_elements.eq(0).find('li').addClass('ui-state-default');
ul_elements.eq(1).find('li').addClass('ui-state-highlight');
var original_order = ul_elements.eq(1).clone();
orig_lis=ul_elements.eq(1).find('li');
while(ul_elements.eq(1).html().replace(/\s*/g,'')==original_order.html().replace(/\s*/g,'')){
orig_lis.sort(function (){return Math.round(Math.random())-0.5;}).appendTo(ul_elements.eq(1));
}
jQuery(this).hide();
$element.find('.skip_button').show();
ul_elements.eq(1).sortable({
disabled:false,
update:function()
{
if (jQuery(this).html().replace(/\s*/g,'').replace(/position:relative;left:0px;top:0px;/g,'')==original_order.html().replace(/\s*/g,'').replace(/position:relative;left:0px;top:0px;/g,'')){
correct_order($element);
jQuery(this).sortable({disabled:true});
}
}
}).disableSelection();
$element.find('.theory_shuffle.sdbooktheory').removeClass('sdbooktheory');
});
}
}
config.macros.browserapp = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var pageurl = params[0] || "http://emath.utu.fi";
var pagename = params[1] || "E-math project";
var browserwindow = jQuery('<div id="browserapp"></div>');
wikify('<html><a href="javascript:;" class="ebookappwinbutton">'+pagename+'</a></html>', place);
jQuery(place).find('.ebookappwinbutton').last().click(function(){
jQuery('#browserapp').remove();
browserwindow.dialog({
title: pagename,
width: 1000,
height: 670,
buttons: [
{
"text": "Min/Max",
"click": function(){
var $app = jQuery(this);
if ($app.hasClass('apphidden')){
$app.removeClass('apphidden').dialog('option','height',670);
} else {
$app.addClass('apphidden').dialog('option','height',120);
}
}
},
{
"text": EbookDictionary.localize("close"),
"click": function(){jQuery(this).dialog('destroy'); jQuery('#browserapp').remove();}
}
]
});
browserwindow.html('<iframe src="'+pageurl+'" width="950px" height="550px" style="background-color: white;"></iframe>');
}).button();
}
};
config.macros.contenttabs = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if(params.length>0){
var tabid = 'ebooktab-'+jQuery(place).parent().find('.ebooktabs').length;
var tabelementbox = jQuery(place).append('<div class="ebooktabs" id="'+tabid+'"></div>').find('#'+tabid);
var tablist = tabelementbox.append('<ul></ul>').find('ul');
for(var i=0;i<(params.length/2);i++){
tablist.append('<li><a href="#'+tabid+'-tabs-'+i+'">'+(i+1)+"."+(params[2*i]?params[2*i]:"")+'</a></li>');
tabelementbox.append('<div id="'+tabid+'-tabs-'+i+'"></div>');
wikify(params[2*i+1].replace(/\\/g,''),tabelementbox.find('#'+tabid+'-tabs-'+i)[0],null,tiddler);
}
tabelementbox.tabs({collapsible: true});
}
}
}
/*
config.macros.helloWorld = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
// this will run when macro is called from a tiddler
var who = params[0] || "world";
wikify('Hello //' + who + '// from the "' + macroName + '" macro in tiddler [[' + tiddler.title + ']].', place);
}
};
*/
//}}}
/***
|''Name:''|SdEmathbookJS|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Emathbook functionalities for TiddlyWiki|
|''Version:''|1.3|
|''Date:''|May 31, 2011|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131006.14.02 ''fix''
* Removed old updatefunctions from "actionMenu"
<<<
<<<
20131003.12.02 ''added feature''
* Support for close button of pageTwo-apps.
<<<
<<<
20130917.09.37 ''fix''
* Moved dictedit button
<<<
<<<
20130913.10.37 ''fix''
* showNextPage when at the end of the book and there is no next page.
<<<
!!!!!Code
***/
//{{{
/* window.onbeforeunload = function(e){ e = e || window.event; autoSaveChanges(); e.returnValue = "Moimoi!"; return "Moimoi!"; } */
Emathbook.config = DataTiddler.getData(Emathbook.config.datatiddler,'config',{"datatiddler": Emathbook.config.datatiddler});
Emathbook.options.loadUserSettings();
var bookshelf = new Emathbookshelf();
var EbookPages = [];
(function(){
// var pages = DataTiddler.getData(Emathbook.config.userdatatiddler, 'ebookpages', {});
var pages = Emathbook.options.user.ebookpages;
var pagemap = {"pageOne": 0, "pageTwo": 1};
for (var page in pages){
EbookPages[pagemap[page]] = new EmathbookPage(page);
EbookPages[pagemap[page]].setBook(bookshelf.getBook(pages[page]["bookid"]));
}
})()
Emathbook.options.loadCourseSettings();
// TODO! These are hardcoded for now.
if (store.getTaggedTiddlers('currentCourse').length > 0){
Emathbook.options.pages[0].courseid = store.getTaggedTiddlers('currentCourse')[0].data('courseid') || '';
Emathbook.options.pages[1].courseid = Emathbook.options.pages[0].courseid;
} else {
Emathbook.options.pages[0].courseid = '';
Emathbook.options.pages[1].courseid = '';
}
/// Temporary fix!!
/// Emathbook.options.pages[0].lang = config.options.txtLang;
/// Emathbook.options.pages[1].lang = config.options.txtLang;
Emathbook.options.pages[0].lang = Emathbook.options.user.ebookpages['pageOne'][Emathbook.options.user.ebookpages['pageOne'].bookid].lang;
Emathbook.options.pages[1].lang = Emathbook.options.user.ebookpages['pageTwo'][Emathbook.options.user.ebookpages['pageTwo'].bookid].lang;
// show book page content
config.macros.showPage = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
wikify('<<tiddler [['+params[0]+']]>>',place);
}
}
config.macros.headerslide = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
jQuery(place).delay(4000).slideUp(3000);
}
}
config.macros.menuaction = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
jQuery(place).toggle(function(){
jQuery(this).addClass('menushow');
jQuery('.header').slideDown('fast');
}, function(){
jQuery(this).removeClass('menushow');
jQuery('.header').slideUp('fast');
});
}
}
config.macros.menugen = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length > 0){
var pagenum = params[0];
} else {
aa = jQuery(place).parent().attr('id')=="pageOne" ? 1:0;
var pagenum = 1-aa;
}
if (typeof(params[1]) == 'undefined'){
var beginLevel = EbookPages[pagenum].currentpage;
}else{
var beginLevel = -1;
}
if (typeof(tiddler) == 'undefined'){
// jQuery(place).empty().append('<div class="bookmenucont">\n'+EbookPages[pagenum].ebook.tocHtml(false,beginLevel)+'</div>\n');
jQuery(place).empty().append('<div class="bookmenucont">\n'+wikifyStatic('<html>'+EbookPages[pagenum].ebook.tocHtml(false,beginLevel)+'</html>')+'</div>');
} else {
wikify('<html>'+EbookPages[pagenum].ebook.tocHtml(false,beginLevel)+'</html>',place);
}
var edata = {'pagenum': pagenum};
jQuery(place).find('div.ebooktoc a').click(edata, function(e){
var chid = jQuery(this).attr('chapid');
jQuery(this).trigger('setpage', [chid]);
jQuery(this).parents('.ebooktoc').eq(0).click();
jQuery(this).parents('li.hassubsections').not('.subshow').eq(0).click();
jQuery(this).parents('li').eq(0).find('li.hassubsections.subshow').click();
return false;
}).parents('.bookmenucont').bind('setpage', edata, function(e, chapid){
EbookPages[e.data.pagenum].setPage(chapid);
jQuery('.navislider').eq(e.data.pagenum).slider( "value", EbookPages[e.data.pagenum].ebook.chapters.indexOf(EbookPages[e.data.pagenum].currentpage) );
e.stopPropagation();
});
jQuery(place).find('.ebooktoc.hidesub > ol > li > ol > li').each(function(){
if (jQuery(this).find('ol').length > 0){
jQuery(this).addClass('hassubsections');
};
});
jQuery(place).find('.ebooktoc li').click(function(){
return false;
});
jQuery(place).find('.ebooktoc.hidesub li.hassubsections').click(function(){
jQuery(this).parents('.ebooktoc.hidesub').find('li.subshow').not(this).removeClass('subshow');
jQuery(this).toggleClass('subshow');
return false;
});
}
}
config.macros.ebooknavi = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length > 0){
var pagenum = params[0];
} else {
var pagenum = 0;
}
var pagetwovisible = DataTiddler.getData(Emathbook.config.userdatatiddler, 'pagetwovisible', false);
if (!!pagetwovisible){
jQuery('#contentWrapper').attr('pageopen', pagetwovisible);
};
var breadcrumb = EbookPages[pagenum].ebook.getBreadcrumb(EbookPages[pagenum].currentpage, EbookPages[pagenum].currentlang);
if (pagenum == 0){
var navibar = '<div class="ebooknavibar">'+Emathbook.showUserName()+'<div class="bcnavi"><div class="bctoc"> </div><div class="breadcrumb"></div></div><div class="naviui"><div class="navibuttonset"><button class="naviprev"><span>Previous</span></button><button class="naviup"><span>Up</span></button><button class="navinext"><span>Next</span></button></div><div class="navislider"></div></div></div>';
} else {
var navibar = '<div class="ebooknavibar"><div class="bcnavi"><div class="bctoc"> </div><div class="breadcrumb"></div></div><div class="naviui"><div class="navibuttonset"><button class="naviprev"><span>Previous</span></button><button class="naviup"><span>Up</span></button><button class="navinext"><span>Next</span></button></div><div class="navislider"></div></div></div>';
}
var edata = {'pagenum': pagenum};
jQuery(place).prepend(navibar);
wikify(('<html>'+breadcrumb+'</html>').replace(/\n/g,''), jQuery(place).find('.breadcrumb')[0]);
jQuery(place).find('.naviprev').button({
'icons': {
primary: "ui-icon-circle-triangle-w"
}
}).click(edata, function(e){
var eve = jQuery.Event('prevpage');
jQuery(this).trigger(eve);
return false;
});
jQuery(place).find('.naviup').button({
'icons': {
primary: "ui-icon-circle-triangle-n"
}
}).click(edata, function(e){
var eve = jQuery.Event('uppage');
jQuery(this).trigger(eve);
return false;
});
jQuery(place).find('.navinext').button({
'icons': {
primary: "ui-icon-circle-triangle-e"
}
}).click(edata, function(e){
var eve = jQuery.Event('nextpage');
jQuery(this).trigger(eve);
return false;
}).parent().buttonset();
jQuery(place).find('.ebooknavibar').bind('prevpage', edata, function(e){
EbookPages[e.data.pagenum].prevPage();
jQuery(this).find('.navislider').slider( "value", EbookPages[e.data.pagenum].ebook.chapters.indexOf(EbookPages[e.data.pagenum].currentpage) );
}).bind('nextpage', edata, function(e){
EbookPages[e.data.pagenum].nextPage();
jQuery(this).find('.navislider').slider( "value", EbookPages[e.data.pagenum].ebook.chapters.indexOf(EbookPages[e.data.pagenum].currentpage) );
}).bind('uppage', edata, function(e){
EbookPages[e.data.pagenum].parentPage();
jQuery(this).find('.navislider').slider( "value", EbookPages[e.data.pagenum].ebook.chapters.indexOf(EbookPages[e.data.pagenum].currentpage) );
}).bind('setpage', edata, function(e, chapid){
EbookPages[e.data.pagenum].setPage(chapid);
jQuery(this).find('.navislider').slider( "value", EbookPages[e.data.pagenum].ebook.chapters.indexOf(EbookPages[e.data.pagenum].currentpage) );
e.stopPropagation();
});
jQuery(place).find('.navislider').slider({
min: 0,
max: EbookPages[pagenum].ebook.chapters.length-1,
range: "min",
value: EbookPages[pagenum].ebook.chapters.indexOf(EbookPages[pagenum].currentpage),
stop: function( event, ui ) {
jQuery(this).trigger('setpage', [EbookPages[pagenum].ebook.chapters[ui.value]]);
}
});
jQuery(place).find('.bcnavi .bctoc').click(function(){
if(jQuery(this).find('.subtocwrapper').length > 0){
jQuery(this).find('.subtocwrapper').remove();
} else {
var pageno = parseInt(jQuery(this).parents('.pageWrapper').attr('pagenumber'));
jQuery('.ebooknavibar .subtocwrapper').remove();
// jQuery(this).append(EbookPages[pageno].getSubToc('front'));
wikify(('<html>'+EbookPages[pageno].getSubToc('front', Emathbook.options.pages[pageno].lang)+'</html>').replace(/\n/g,''), jQuery(this)[0]);
jQuery(this).find('.subtocwrapper .subtocitem a').click(function(){
var tochapid = jQuery(this).parents('.subtocitem').eq(0).attr('chapid');
jQuery(this).trigger('setpage', [tochapid]);
});
}
});
jQuery(place).find('.breadcrumbchapter').click(function(){
if(jQuery(this).find('.subtocwrapper').length > 0){
jQuery(this).find('.subtocwrapper').remove();
} else {
var pageno = parseInt(jQuery(this).parents('.pageWrapper').attr('pagenumber'));
jQuery('.ebooknavibar .subtocwrapper').remove();
var chapid = jQuery(this).attr('chapid');
if (EbookPages[pageno].ebook.tocdict[chapid].chapters.length > 0){
// jQuery(this).append(EbookPages[pageno].getSubToc(jQuery(this).attr('chapid')));
wikify(('<html>'+EbookPages[pageno].getSubToc(chapid, Emathbook.options.pages[pageno].lang)+'</html>').replace(/\n/g,''), jQuery(this)[0]);
}
jQuery(this).find('.subtocwrapper .subtocitem a').click(function(){
var tochapid = jQuery(this).parents('.subtocitem').eq(0).attr('chapid');
jQuery(this).trigger('setpage', [tochapid]);
});
}
});
var slider = jQuery(place).find('.navislider');
var ebook = EbookPages[pagenum].ebook;
var defaultlang = Emathbook.options.pages[pagenum]["defaultlang"];
var pagelang = Emathbook.options.pages[pagenum].lang;
for (var i = 0; i<ebook.frontpage.chapters.length; i++){
if(defaultlang != pagelang && ebook.frontpage.chapters[i].alttitles && ebook.frontpage.chapters[i].alttitles[pagelang]){
var ctitle = ebook.frontpage.chapters[i].alttitles[pagelang];
}else{
var ctitle = ebook.frontpage.chapters[i].title;
}
var xplace = 100 * ebook.chapters.indexOf(ebook.frontpage.chapters[i].chapid)/(ebook.chapters.length-1);
slider.append('<div class="chapstop" id="chapstop-'+i+'" ctitle="'+ctitle+'" style="left:'+xplace+'%;"></div>');
}
slider.find('.chapstop').each(function(){
var ctitle = jQuery(this).attr('ctitle');
jQuery(this).append('<div class="cnavi"><a href="javascript:;">'
+(parseInt(slider.find('.chapstop').index(jQuery(this)))+1)
+'</a><span class="ctitletext">'+ctitle+'</span></div>');
});
if (pagenum == 0){
jQuery('.showusername .usernametext a').click(function(){
Emathbook.promptUserName();
});
}
}
}
config.macros.pageselect = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var html = '<html><div class="pageselect"> </div></html>';
wikify(html, place);
jQuery(place).find('.pageselect').click(function(){
var pagetwovisible = DataTiddler.getData(Emathbook.config.userdatatiddler, 'pagetwovisible', false);
if (!pagetwovisible) {
jQuery('#contentWrapper').attr('pageopen', 'bookpage');
pagetwovisible = 'bookpage';
} else {
jQuery('#contentWrapper').removeAttr('pageopen');
pagetwovisible = false;
}
DataTiddler.setData(Emathbook.config.userdatatiddler, 'pagetwovisible', pagetwovisible);
});
}
}
config.macros.actionbuttons = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
if(Emathbook.initType==="author" || !Emathbook.initType){
// var buttonbar = '<div class="buttonbar"><div class="actionbuttonset"><button class="addcomment"><span>Add marking</span></button><input type="checkbox" id="showcomments" title="Show comments"/><label for="showcomments"> </label></div> <span class="pagecommbutton"><button class="pagecommentbutton"><span>Comment this page</span></button></span> <span class="updatebuttonset"></span> <span class="editbuttonset"></span><span class="attachbuttonset"></span></div>';
var buttonbar = '<div class="buttonbar"> <span class="updatebuttonset"></span> <span class="editbuttonset"></span><span class="attachbuttonset"></span></div>';
jQuery(place).prepend(buttonbar);
var edata = {};
// jQuery(place).find('#showcomments').button({
// icons: {primary: 'ui-icon-pencil'}
// }).change(function(){
// if (jQuery(this).attr('checked')){
// Emathbook.config.showcomments = true;
// var showcomm = new EbHighlight();
// showcomm.showComments();
// } else {
// Emathbook.config.showcomments = false;
// refreshDisplay();
// }
// });
// jQuery(place).find('.addcomment').button({
// 'icons': {
// primary: "ui-icon-comment"
// }
// }).click(edata, function(e){
// if (Emathbook.config.showcomments){
// var comment = new EbHighlight();
// comment.getSelection();
// if (typeof comment.text == 'undefined' || comment.text == ''){
// return false;
// }
// comment.editComment();
// return false;
// } else {
// alert(EbookDictionary.localize('set comment tool on first'));
// return false;
// }
// });
jQuery(place).find('.actionbuttonset').buttonset();
// jQuery(place).find('.pagecommentbutton').button({
// 'icons': {
// primary: "ui-icon-comment"
// }
// }).click(edata, function(e){
// var commtool = new Authortool();
// commtool.pageComment();
// });
// Update-menu
var UpdateMenuElement = jQuery('#actionButtons .buttonbar .updatebuttonset');
var updateMenu = new Actionmenu('update',function(){},function(){});
updateMenu.addMenu(UpdateMenuElement);
UpdateMenuElement.buttonset();
updateMenu.pushItem({name: 'Check updates', contexts: [], click: function(){
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
if (confirm(EbookDictionary.localize('about to update'))){
Emathbook.initBook('author');
}
}, level: 0});
//AttachMenu
var AttaachMenuElement = jQuery('#actionButtons .buttonbar .attachbuttonset');
var attachmenu = new Actionmenu('Attach image', function(){this.tool = new Authortool(); this.tool.startAuthoring('addimage');}, function(){refreshElements(jQuery('#pageOneWrapper')[0])});
attachmenu.addMenu(AttaachMenuElement);
AttaachMenuElement.buttonset();
// Menu-elements
var authorEditMenuElement = jQuery('#actionButtons .buttonbar .editbuttonset');
var addmenu = new Actionmenu('Add', function(){}, function(){});
addmenu.addMenu(authorEditMenuElement);
var removemenu = new Actionmenu('Remove', function(){}, function(){});
removemenu.addMenu(authorEditMenuElement);
var editmenu = new Actionmenu('Edit', function(){this.tool = new Authortool(); this.tool.startAuthoring('edit');}, function(){refreshElements(jQuery('#pageOneWrapper')[0])});
editmenu.addMenu(authorEditMenuElement);
var ordermenu = new Actionmenu('Order', function(){this.tool = new Authortool(); this.tool.startAuthoring('order');}, function(){refreshElements(jQuery('#pageOneWrapper')[0]); jQuery('#pageOneNavi').show();});
ordermenu.addMenu(authorEditMenuElement);
var toceditmenu = new Actionmenu('Edit TOC', function(){this.tool = new Authortool(); this.tool.startAuthoring('tocstructure');}, function(){refreshElements(jQuery('#pageOneWrapper')[0]); refreshElements(jQuery('#pageTwoWrapper')[0])});
toceditmenu.addMenu(authorEditMenuElement);
//var toceditmenu = new Actionmenu('TOC structure', function(){this.tool = new Authortool(); this.tool.startAuthoring('tocstructure');}, function(){});
//toceditmenu.addMenu(authorEditMenuElement);
var copymenu = new Actionmenu('Copy', function(){this.tool = new Authortool(); this.tool.startAuthoring('copyelement');}, function(){refreshElements(jQuery('#pageOneWrapper')[0]); refreshElements(jQuery('#pageTwoWrapper')[0])});
copymenu.addMenu(authorEditMenuElement);
var dicteditmenu = new Actionmenu(EbookDictionary.localize('edit dictionary'), function(){this.tool = new Authortool(); this.tool.startAuthoring('dictedit');}, function(){refreshElements(jQuery('#pageOneWrapper')[0]); refreshElements(jQuery('#pageTwoWrapper')[0])});
dicteditmenu.addMenu(authorEditMenuElement);
authorEditMenuElement.buttonset();
// Add -menu
addmenu.pushItem({name:'SD-Assignment',contexts:['frontPage','section','subsection','chapter'],click: function(){cc = new Authortool(); cc.startAuthoring('addassignment');}, level: 1});
addmenu.pushItem({name:'Simple-Assignment',contexts:['frontPage','section','subsection','chapter'],click: function(){cc = new Authortool(); cc.startAuthoring('addotherassignment');}, level: 1});
addmenu.pushItem({name: 'Extra', contexts: ['frontPage','chapter','section','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('addextra');}, level: 1});
addmenu.pushItem({name: 'Hint', contexts: ['frontPage','chapter','section','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('addhint');}, level: 1});
addmenu.pushItem({name: 'Example', contexts: ['frontPage','chapter','section','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('addexample');}, level: 1});
addmenu.pushItem({name: 'Theory', contexts: ['frontPage','chapter','section','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('addtheory');}, level: 1});
addmenu.pushItem({name: 'Text element', contexts: ['frontPage','chapter','section','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('addtext');}, level: 1});
addmenu.pushItem({name: 'Prerequisites', contexts: ['frontPage','assignments','subsection'], click:function(){cc = new Authortool(); cc.startAuthoring('addprerequisites');}, level: 1});
addmenu.pushItem({name: 'Discussion', contexts: ['frontPage','assignments'], click:function(){cc = new Authortool(); cc.startAuthoring('adddiscussion');}, level: 1});
addmenu.pushItem({name: 'History', contexts: ['frontPage','assignments','subsection'], click:function(){cc = new Authortool(); cc.startAuthoring('addhistory');}, level: 1});
addmenu.pushItem({name: 'DidYouKnow', contexts: ['frontPage','assignments','subsection'], click:function(){cc = new Authortool(); cc.startAuthoring('adddidyouknow');}, level: 1});
addmenu.pushItem({name: 'Cancel', contexts: [], click: function(){refreshElements(jQuery('#pageOneWrapper')[0]);jQuery('#pageOneNavi').show(); cc = new Authortool(); cc.removeLock();}, level: 2});
// Remove -menu
removemenu.pushItem({name: 'Remove element', contexts: [], click: function(){this.parent.tool = new Authortool(); this.parent.tool.startAuthoring('remove');}, level: 1});
removemenu.pushItem({name: 'Done', contexts: [], click:function(){this.parent.tool.removeInTiddler();}, level: 2});
removemenu.pushItem({name: 'Cancel', contexts: [], click: function(){refreshElements(jQuery('#pageOneWrapper')[0]);jQuery('#pageOneNavi').show();this.parent.tool.removeLock();}, level: 2});
// Edit -menu
editmenu.pushItem({name: 'Cancel', contexts: [], click: function(){this.parent.tool.cancel();refreshElements(jQuery('#pageOneWrapper')[0]);refreshElements(jQuery('#pageTwoWrapper')[0]);jQuery('#pageOneNavi').show(); this.parent.menuelement.children('button').click();this.parent.tool.removeLock();}, level: 0});
// Order -menu
ordermenu.pushItem({name: 'Done', contexts: [], click:function(){this.parent.tool.orderElementDo();}, level: 0});
ordermenu.pushItem({name: 'Cancel', contexts: [], click: function(){refreshElements(jQuery('#pageOneWrapper')[0]);jQuery('#pageOneNavi').show();this.parent.tool.removeLock();}, level: 0});
// TOC-Edit -menu
// Ei tartte. On oma cancel.
// toceditmenu.pushItem({name: 'Cancel', contexts: [], click: function(){this.parent.tool.cancel();refreshElements(jQuery('#pageOneWrapper')[0]); this.parent.menuelement.children('button').click();this.parent.tool.removeLockType();}, level: 0});
// Copy -menu
copymenu.pushItem({name: 'Cancel', contexts: [], click: function(){refreshElements(jQuery('#pageOneWrapper')[0]); refreshElements(jQuery('#pageTwoWrapper')[0]); this.parent.menuelement.children('button').click();jQuery('#pageOneNavi').show();this.parent.tool.callFifo = []; this.parent.tool.removeLock(), this.parent.tool.removeLockType();}, level: 0});
copymenu.pushItem({name: 'Copy selected', contexts: ['frontPage','subsection','chapter'], click:function(){this.parent.tool.copyAssignment();}, level: 0});
EbookPages[0].setButtonContext();
}else{
jQuery(place).remove();return true;
}
}
}
config.macros.ebookgraph = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
if (params.length < 2){
wikify('{{sdalert{ebookgraph: missing some arguments}}}', place);
return false;
}
var tiddlername = params[0];
var boxclassstart = '';
var boxclassend = '';
var pageId = $tiddler.parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
if(Emathbook.options && !(params[2]=="savehere")){
if (Emathbook.options.pages[pageNro].lang != Emathbook.options.pages[pageNro]["defaultlang"]){
if(store.tiddlerExists(params[0]+'_'+Emathbook.options.pages[pageNro].lang)){
//Tähän myös lang
tiddlername = params[0]+'_'+Emathbook.options.pages[pageNro].lang;
}else{
boxclassstart = '{{notTranslatedimage{\n';
boxclassend = '\n}}}';
}
}
}
var graphtype = params[1];
switch (graphtype){
case 'image':
var classes = ['ebookimage'];
var imagetag = (store.getTiddlerText(tiddlername+'##image') || '').trim();
var imagetiddler = imagetag.replace(/^\[img\[/,'').replace(/\]\]$/,'');
var imagecaption = (store.getTiddlerText(tiddlername+'##caption') || '').trim();
var imagesizex = (store.getTiddlerText(tiddlername+'##size-x') || 'auto').trim();
var imagesizey = (store.getTiddlerText(tiddlername+'##size-y') || 'auto').trim();
var author = (store.getTiddlerText(imagetiddler+'##author') || '').trim();
var license = (store.getTiddlerText(imagetiddler+'##license') || '').trim();
var source = (store.getTiddlerText(imagetiddler+'##source') || '').trim();
var moreclasses = (store.getTiddlerText(tiddlername+'##classes') || '').trim().split(' ');
var credits = [];
if (author != ''){credits.push('Author: '+author);}
if (license != ''){credits.push('License: '+license);}
if (source != ''){credits.push('Source: '+source);}
imagetag = imagetag.replace('[img[', '[img['+credits.join(', ')+' |');
classes = classes.concat(moreclasses);
var contclass = classes.join(' ');
var captionbox = '';
if (imagecaption != ''){
captionbox = '{{imgcaption{\n'+imagecaption+'}}}';
}
var wikitext = '{{'+contclass+'{\n'+imagetag+captionbox+'}}}';
wikify(boxclassstart + wikitext + boxclassend, place);
jQuery(place).find('.ebookimage img').last().css('width',imagesizex).css('height',imagesizey);
jQuery(place).find('.ebookimage').last().attr('tiddler', tiddlername);
break;
case 'functiongraph':
if (params.length > 2 && params[2] == 'savehere'){
var graphname = params[0];
tiddlername = tiddler.title;
} else {
var graphname = 'graph1';
}
var contclass = 'ebookgraph';
var allgraphdata = DataTiddler.getData(tiddlername, 'graphs', {'graph1': {'sliders': [],'data': [], 'caption': '', 'sizex': 'auto', 'sizey': 'auto', 'axis': true, 'grid': true, 'area': [0,10,10,0]}});
var graphdata = allgraphdata[graphname] || {'sliders': [],'data': [], 'caption': '', 'sizex': 'auto', 'sizey': 'auto', 'axis': true, 'grid': true, 'area': [0,10,10,0]};
var elementid = "x" + tiddlername.replace(/\ :/g,'')+'_graph_';
var i = 0;
while (jQuery('#'+elementid+i).length > 0){
i++;
}
elementid = elementid+i;
var sliderid = tiddlername.replace(/\ :/g,'')+'_slider_';
var sliderids =[];
var i = 0;
var j = 0;
if (typeof(graphdata.sliders) != 'undefined'){
while (j < graphdata.sliders.length){
while (jQuery('#'+sliderid+(i+j)).length > 0){
i++;
}
sliderids.push(sliderid+(i+j));
j++;
}
for(var i=0;i<5;i++){
if (typeof(graphdata.sliders[i]) != 'undefined'){eval(elementid+'s'+i+'=parseFloat(graphdata.sliders['+i+'].value);');}
}
}
var funclist = '<ul>\n';
for (var i = 0; i < graphdata.data.length; i++){
var returnfunction = 'return (' + graphdata.data[i].formula_js + ')';
returnfunction = returnfunction.replace(/(s[0-4])/g,elementid+'$1');
graphdata.data[i].func = new Function('x',returnfunction);
funclist += '<li class="color_'+graphdata.data[i].color+'">\\('+graphdata.data[i].label+'\\)</li>\n';
}
funclist += '</ul>\n';
function drawgraph(elementid, sliderids){
var axis = graphdata.axis || false;
var grid = graphdata.grid || false;
for (var i = 0; i < sliderids.length;i++){
jQuery('#'+sliderids[i]).slider({
orientation: "horizontal",range: "min",min: parseFloat(graphdata.sliders[i].min), max: parseFloat(graphdata.sliders[i].max), value: parseFloat(graphdata.sliders[i].value),
slide: new Function('event','ui',elementid+'s'+i+' = ui.value;jQuery("#'+sliderids[i]+'_value").empty().html(ui.value);'+elementid+'board.updateQuality = '+elementid+'board.BOARD_QUALITY_HIGH;'+elementid+'board.update();')
});
if (graphdata.sliders[i].step !='undefined'){
jQuery( '#'+sliderids[i] ).slider( 'option', 'step', parseFloat(graphdata.sliders[i].step) );
}
}
eval(elementid+'board = JXG.JSXGraph.initBoard(elementid, {boundingbox:graphdata.area, axis:axis, grid: grid, keepaspectratio: true, showCopyright: false});\
JXG.removeEvent('+elementid+'board.containerObj, "mousewheel", '+elementid+'board.mouseWheelListener, '+elementid+'board);\
JXG.removeEvent('+elementid+'board.containerObj, "DOMMouseScroll", '+elementid+'board.mouseWheelListener, '+elementid+'board);');
for (var i = 0; i < graphdata.data.length; i++){
switch (graphdata.data[i]["type"]){
case "function":
eval(elementid+"board.create('functiongraph',[graphdata.data[i].func],{strokeColor: graphdata.data[i].color, strokeWidth: 3*(Math.pow(0.9,i))});");
break;
case "point":
eval(elementid+"board.create('point', [graphdata.data[i].xcoord, graphdata.data[i].ycoord], {fillColor: graphdata.data[i].color, face: 'o', name: '', strokeWidth: 0, fixed: true});");
}
}
}
var slidertext='';
if (sliderids.length >0){slidertext = slidertext+'<div class="graph_sliders">';}
for (var i =0;i<sliderids.length;i++){
slidertext = slidertext+'<div class="slider_element"><div class="slider_data"><span class="slider_label">'+graphdata.sliders[i].label+'</span><span class="graph_slider_value" id="'+sliderids[i]+'_value"></span></div><div class="graph_slider" id="'+sliderids[i]+'"></div></div>';
}
if (sliderids.length >0){slidertext = slidertext+'</div>';}
var area = graphdata.area;
var xyscale = (area[3]-area[1])/(area[0]-area[2]);
var width = graphdata.sizex +'px';
var height = (xyscale * graphdata.sizex) +'px';
var caption = '';
if (graphdata.caption != ''){
caption = '<div class="graphcaption"><p>'+graphdata.caption+'</p></div>';
}
var wikitext = '<html><div class="functiongraph"><div class="jsxgfunclist">'+funclist+'</div><div id="'+elementid+'" class="jxgbox" style="width:'+width+';height:'+height+'; margin-left: auto; margin-right: auto;"></div>'+slidertext+caption+'</div></html>';
wikify(boxclassstart + wikitext + boxclassend, place);
for (var i =0;i<sliderids.length;i++){
jQuery('#'+sliderids[i]+'_value').html(parseFloat(graphdata.sliders[i].value));
}
drawgraph(elementid, sliderids);
break;
default:
break;
}
}
}
config.macros.pageinit = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
// What to do with firstload
if (Emathbook.options.system.firstload){
//
// typekset molempiin sivuihin joihen tiedot haetaan userdatan currenpageiden avulla
// Mahdollisesti lang kielitietoja molemmille sivuille
// mahdollisesti nettiyhteystesti
// olisko autopäivitys
//
jQuery('#pageOne').attr('types', EbookPages[0].ebook.tocdict[EbookPages[0].currentpage].types.join(' '));
jQuery('#pageTwo').attr('types', EbookPages[1].ebook.tocdict[EbookPages[1].currentpage].types.join(' '));
Emathbook.options.system.firstload = false;
}
var pageno = 0;
var parentpage = jQuery(place).parents('.pageWrapper').scrollTop(0).find('.bookpage').index('.bookpage');
if (params.length > 0){
pageno = parseInt(params[0]) || 0;
}
// Set Theory and Example numbers
EbookPages[pageno].setElementNumbers(parentpage);
// For courseBooks only
if(typeof(Authortool) !=="function"){
var authormodels = EbookPages[pageno].getModelsolutions(parentpage);
EbookPages[pageno].setTeacherElements(parentpage,authormodels);
}
if(typeof(Emathbook.options.user.showstepbystep) !== "undefined" && Emathbook.options.user.showstepbystep){
try{
Emathbook.showStepByStep(pageno);
} catch (err) {}
}
if(typeof(Emathbook.sendOfflineCourseContent)==="function"){
Emathbook.sendOfflineCourseContent();
}
}
}
config.macros.ebookshelf = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('{{sdalert{ebookshelf: missing some arguments}}}', place);
return false;
}
var page = params[0];
jQuery(place).append('<div class="ebookshelfbutton"></div><div class="ebookshelfwrapper"><div class="ebookshelfcontainer"><div class="ebookshelf_apps"></div><div class="ebookshelf_books"></div></div></div>');
jQuery(place).find('.ebookshelfbutton').click(function(){
jQuery(this).parents('.toolmenu').toggleClass('menuopen');
});
var container = jQuery(place).find('.ebookshelfcontainer');
var bookshelfhtml = bookshelf.getHtml(page);
if (bookshelfhtml){
container.find('.ebookshelf_books').append('<h1>'+EbookDictionary.localize('textbooks')+'</h1>').append(bookshelfhtml);
}
var ebookapps = bookshelf.getAppsHtml();
if (page == 1 && ebookapps){
container.find('.ebookshelf_apps').append(ebookapps);
}
container.find('li[bookid="'+Emathbook.options.pages[page].currentcontent+'"]').addClass('currentbook');
if (container.parents('.ebookshelfcontainer').find('.currentbook, .currentapp').length == 0){
container.find('li[bookid="'+EbookPages[page].ebook.bookid+'"]').addClass('currentbook');
}
var edata = {pageno: page}
container.find('li.bookshelfitem a').click(edata, function(e){
var pagelist = ['pageOne','pageTwo'];
var bookid = jQuery(this).parents('li.bookshelfitem').attr('bookid');
EbookPages[e.data.pageno].changeBook(bookshelf.getBook(bookid));
Emathbook.options.pages[e.data.pageno].currentcontent = bookid;
Emathbook.options.pages[e.data.pageno].lang = Emathbook.options.user.ebookpages[pagelist[e.data.pageno]][bookid].lang;
jQuery(this).parents('.ebookshelfcontainer').find('li.applistitem.currentapp').removeClass('currentapp');
jQuery(this).parents('ul.bookshelf').find('li.bookshelfitem').removeClass('currentbook');
jQuery(this).parents('li.bookshelfitem').addClass('currentbook');
jQuery('#'+pagelist[e.data.pageno]+'Wrapper.hideNavi').removeClass('hideNavi');
jQuery(this).parents('.toolmenu.menuopen').find('.ebookshelfbutton').click();
if (e.data.pageno == 1){
jQuery('#contentWrapper').removeClass('pageclosed').attr('pageopen','bookpage');
Emathbook.options.user.pagetwovisible = 'bookpage';
Emathbook.options.saveUserSettings();
}
var refresh = jQuery(this).parent().attr('refresh');
Emathbook.options.pages[e.data.pageno].refresh = (refresh == '1');
return false;
});
container.find('li.bookshelfitem a li.booklang span').click(edata,function(e){
var bookid = jQuery(this).parents('li.bookshelfitem').attr('bookid');
var pagelist = ['pageOne','pageTwo'];
var thislang = jQuery(this).text();
Emathbook.options.user.ebookpages[pagelist[e.data.pageno]][bookid].lang = thislang;
Emathbook.options.saveUserSettings();
jQuery(this).parents('ul.bookitemlangs').find('li.currentlang').removeClass('currentlang');
jQuery(this).parents('li.booklang').addClass('currentlang');
});
container.find('li.applistitem a').click(function(){
jQuery(this).parents('.toolmenu.menuopen').find('.ebookshelfbutton').click();
var openpage = jQuery(this).parent().attr('openpage');
var appclosebutton = jQuery(this).parent().attr('data-closebutton');
if (openpage) {
jQuery('#contentWrapper').removeClass('pageclosed elementselectmode').attr('pageopen', openpage);
Emathbook.options.user.pagetwovisible = openpage;
}else{
jQuery('#contentWrapper').removeClass('elementselectmode').removeAttr('pageopen');
Emathbook.options.user.pagetwovisible = openpage;
}
var tiddler = store.getTiddler('pageTwo');
var content = jQuery(this).parents('li.applistitem').attr('content');
var text = '<<tiddler [['+content+']]>>';
tiddler.set(tiddler.title, text);
refreshElements(jQuery('#pageTwoWrapper')[0], ['pageTwo']);
jQuery(this).parents('.ebookshelfcontainer').find('li.bookshelfitem.currentbook').removeClass('currentbook');
jQuery(this).parents('ul.applist').find('li.applistitem').removeClass('currentapp');
jQuery(this).parents('li.applistitem').addClass('currentapp');
jQuery('#pageTwoWrapper').addClass('hideNavi');
if (appclosebutton) {
jQuery('#pageTwo').prepend('<div class="closepagetwobutton"><span>'+EbookDictionary.localize('close')+'</span></div>');
jQuery('#pageTwo .closepagetwobutton').click(function(){Emathbook.closePageTwo();});
}
var refresh = jQuery(this).parent().attr('refresh');
Emathbook.options.pages[1].refresh = (refresh == '1');
Emathbook.options.pages[1].currentcontent = content;
Emathbook.options.saveUserSettings();
autoSaveChanges();
return false;
});
}
}
config.macros.showNextPage = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
Emathbook.options.pages[1].lang = Emathbook.options.pages[0].lang;
var ebook = EbookPages[0].ebook;
var thispage = EbookPages[0].currentpage;
var nextpage = ebook.nextPage(thispage);
if (thispage === nextpage) {
var wikitext = '';
} else {
var pagetypes = ebook.tocdict[nextpage].types;
jQuery(place).parents('.bookpage').attr('types', pagetypes.join(' '));
if (!!ebook.tocdict[nextpage].alttitles){
var ebooktitle = ebook.tocdict[nextpage].alttitles[Emathbook.options.pages[0].lang] || ebook.tocdict[nextpage].title || '';
} else {
var ebooktitle = ebook.tocdict[nextpage].title || '';
}
var headimagetext = ebook.getHeadimage(nextpage);
var headstyle = headimagetext ? ' style="background-image: url('+headimagetext+');"' : '';
var wikitext = '<html><h1 class="ebooktitle"'+headstyle+'>'+ebooktitle+'</h1></html>\n<<tiddler [[' + EbookPages[0].ebook.getContentById(nextpage) + ']]>>';
}
wikify(wikitext, place);
}
}
config.macros.closePageTwo = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
jQuery('#contentWrapper').addClass('pageclosed').removeAttr('pageopen');
Emathbook.options.user.pagetwovisible = false;
Emathbook.options.saveUserSettings();
}
}
config.macros.showCommentList = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var commentnavi = jQuery(place).append('<div id="coursecommentnavi"></div>').find('#coursecommentnavi');
var hideHiddens = (tiddler.data() && tiddler.data().hidden) || 'hide';
var allPagecomments = store.reverseLookup('authorcommenttoid',EbookPages[0].ebook.bookid,true ,'-modified');
if(allPagecomments.length>0){
commentnavi = commentnavi.append('<ul id="commentList"></ul>').find('ul#commentList');
for (var i=0 ;i<allPagecomments.length;i++){
var subcomments = {"general":{"date": allPagecomments[i].modified,"hidden": (allPagecomments[i].isTagged('hidegeneral')?'hide':'show'), "text":allPagecomments[i].text.replace(/\n*<data>.*<\/data>\n*/,'')}};
jQuery.extend(subcomments, allPagecomments[i].data('pagecomments',{}));
for (var commtype in subcomments){
if (subcomments[commtype].text != ''){
if((hideHiddens ==='hide' && !(subcomments[commtype].hidden ==="hide"))||(hideHiddens ==='show')){
commentnavi.append('<li class="'+commtype+' selectComment '+allPagecomments[i].fields.commentto+'" commentto="'+EbookPages[0].ebook.getIdByTiddler(allPagecomments[i].fields.commentto)+'">'+(!(subcomments[commtype].hidden ==="hide")?'<button class="hideComment" commentType="'+commtype+'" commentTiddler="'+allPagecomments[i].title+'">'+EbookDictionary.localize('hide')+'</button>':'')+'<span class="commentSent">'+allPagecomments[i].modified+'</span>: <span class="commentSender">'+allPagecomments[i].creator+'</span> <span class="pagecommenttype">'+commtype+'</span> <span class="commentToText">'+EbookPages[0].ebook.getNumberedTitle(EbookPages[0].ebook.getIdByTiddler(allPagecomments[i].fields.commentto))+'</span></li>');
}
}
}
}
}
commentnavi.find('.selectComment').click(function(){
EbookPages[0].setPage(jQuery(this).attr('commentto'));
});
commentnavi.find('.hideComment').click(function(){
var hidebutton = jQuery(this);
var commentType = hidebutton.attr('commentType');
var hideTiddler = store.getTiddler(hidebutton.attr('commentTiddler'));
var oldmodified = hideTiddler.modified;
if(commentType ==='general'){
hideTiddler.tags.push('hidegeneral');
hideTiddler.set(null,null,null,oldmodified);
hidebutton.parent().remove();
}else{
var commentData = hideTiddler.data('pagecomments');
commentData[commentType].hidden = 'hide';
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(hideTiddler ,'pagecomments', commentData,{});
hideTiddler.set(null,null,null,oldmodified);
config.options.chkAutoSave = autosavestatus;
}
refreshElements(jQuery("#pageTwo")[0]);
});
commentnavi.after('<button id="updatecoursecomments">'+EbookDictionary.localize('update from server')+'</button>');
jQuery('#pageTwo #updatecoursecomments').button().click(function(){
Emathbook.getPageComments([EbookPages[0].ebook.bookid]);
});
jQuery('#pageTwo #updatecoursecomments').after('<button id="showHidden">'+(hideHiddens ==='hide'?EbookDictionary.localize('Show hidden'):EbookDictionary.localize('Hide hidden'))+'</button>');
jQuery('#pageTwo #showHidden').button().click(function(){
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(tiddler.title, 'hidden', (hideHiddens ==='hide'?'show':'hide'),'hide');
tiddler.set();
config.options.chkAutoSave = autosavestatus;
refreshElements(jQuery("#pageTwo")[0]);
});
}
}
config.macros.showPageComments = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var currentpage = EbookPages[0].getCurrentTiddlerName();
var text = '{{pagecommentlist{\n!'+EbookDictionary.localize('Comments on page')+'\n!!' + EbookPages[0].getNumberedTitle() + '\n';
var allcomments = store.reverseLookup('commentto',currentpage,true,'modified');
for (var i = 0; i < allcomments.length; i++){
var subcomments = {"general":{"date": allcomments[i].modified, "text":allcomments[i].text.replace(/\n*<data>.*<\/data>\n*/,'')}};
jQuery.extend(subcomments, allcomments[i].data('pagecomments',{}));
for (var commtype in subcomments){
if (subcomments[commtype].text != ''){
text += '{{pagecommentblock '+commtype+(subcomments[commtype].hidden ==='hide' || (commtype ==='general' && allcomments[i].isTagged('hidegeneral'))?' hiddencommentblock':'')+'{\n{{pagecommenthead{\n{{pagecommenttype{'+commtype+'}}} {{pagecommentauthor{'+allcomments[i].creator+'}}} {{pagecommentdate{'+subcomments[commtype].date+'}}} }}}{{pagecommentbody'+(subcomments[commtype].hidden ==='hide' || (commtype ==='general' && allcomments[i].isTagged('hidegeneral'))?' hidecommentbody':' '+allcomments[i].title)+'{\n'+subcomments[commtype].text+'\n}}} }}}';
}
}
}
if (allcomments.length > 0 && jQuery('#pageOne h1.ebooktitle a.commentsnotify').length == 0){
var titleplace = jQuery('#pageOne h1.ebooktitle');
var commbutton = jQuery('<a href="javascript:;" class="commentsnotify"></a>');
wikify('[img[icon-comment.png]]',commbutton[0]);
commbutton.click(function(){
jQuery('#contentWrapper').removeClass('pageclosed');
DataTiddler.setData(Emathbook.config.userdatatiddler, 'pagetwovisible', true);
});
titleplace.append(commbutton);
}
text += '}}}';
wikify(text,place);
var hideHiddens = (tiddler.data() && tiddler.data().hidden) || 'hide';
if(((tiddler.data() && tiddler.data().hidden) || 'hide') ==='hide'){
jQuery(place).find('.hidecommentbody').hide().prev().append('<button class="showcommentbody">'+EbookDictionary.localize('show')+'</botton>');
jQuery(place).find('.showcommentbody').click(function(){
jQuery(this).parent().next().toggle();
});
}
jQuery(place).find('.pagecommentbody:not(.hidecommentbody)').append('<button class="hideComment">'+EbookDictionary.localize('hide')+'</button>');
jQuery(place).find('.hideComment').click(function(){
var hidebutton = jQuery(this);
var commentType = hidebutton.parent().parent().attr('class').replace('pagecommentblock ','');
var hideTiddler = store.getTiddler(hidebutton.parent().attr('class').replace('pagecommentbody ',''));
var oldmodified = hideTiddler.modified;
if(commentType ==='general'){
hideTiddler.tags.pushUnique('hidegeneral');
hideTiddler.set(null,null,null,oldmodified);
hidebutton.parent().remove();
}else{
var commentData = hideTiddler.data('pagecomments');
commentData[commentType].hidden = 'hide';
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(hideTiddler ,'pagecomments', commentData,{});
hideTiddler.set(null,null,null,oldmodified);
config.options.chkAutoSave = autosavestatus;
}
refreshElements(jQuery("#pageTwo")[0]);
});
}
}
config.macros.showAllPageComments = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
jQuery('#contentWrapper').hide();
var Wrapper = jQuery('body').append('<div id="AllcommentsWrapper" class="pageWrapper"></div>')
.find('#AllcommentsWrapper');
Wrapper.append('<div class="close_begin closebuttom"><button class="close_allcomments">Close</button></div><div id="showAllPageComments"></div><div class="close_end closebuttom"><button class="close_allcomments">Close</button></div>')
.find('button.close_allcomments').click(function(){
jQuery('#contentWrapper').show();
Wrapper.remove();
});
var ebookChapterlist = EbookPages[0].ebook.chapters;
var currentpage ="";
var text='\n!Comments on page\'s in book '+EbookPages[0].ebook.title.replace('--','-')+'\n';;
for(var j=0;j<ebookChapterlist.length;j++){
var onetext="";
currentpage = EbookPages[0].ebook.getContentById(ebookChapterlist[j]);
onetext += '{{pagecommentlist{\n!!' + EbookPages[0].ebook.getNumberedTitle(ebookChapterlist[j]) + '\n';
var allcomments = store.reverseLookup('commentto',currentpage,true,'modified');
for (var i = 0; i < allcomments.length; i++){
var subcomments = {"general":{"date": allcomments[i].modified, "text":allcomments[i].text.replace(/\n*<data>.*<\/data>\n*/,'')}};
jQuery.extend(subcomments, allcomments[i].data('pagecomments',{}));
for (var commtype in subcomments){
if (subcomments[commtype].text != ''){
onetext += '{{pagecommentblock '+commtype+'{\n{{pagecommenthead{\n{{pagecommenttype{'+commtype+'}}} {{pagecommentauthor{'+allcomments[i].creator+'}}} {{pagecommentdate{'+subcomments[commtype].date+'}}} }}}{{pagecommentbody{\n'+subcomments[commtype].text+'\n}}} }}}';
}
}
}
if(allcomments.length>0){text +=onetext + '}}}\n----\n';}
}
wikify(text, Wrapper.find('#showAllPageComments')[0]);
// Wrapper.css('padding-right','18em').css('padding-top','3em').css('padding-left','8em').css('margin','2em').css('background-color','white').css('border','3px solid red').css('border-radius','15px');
//Test with: wikify('<<showAllPageComments>>', jQuery('#pageOne')[0]);
}
}
config.macros.ebookauthors = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var pagenum = ["pageOne","pageTwo"].indexOf(jQuery(place).parents('.bookpage').attr('id'));
if (typeof pagenum === 'undefined'){
pagenum = 0;
}
var ebook = EbookPages[pagenum].ebook;
var ebauthors = [];
for (var i = 0; i<ebook.author.length; i++){
if (typeof(ebook.author[i]) === 'string'){
ebauthors.push('<span class="ebauthor">'+ebook.author[i]+'</span>');
} else {
var ebgroup = '<div class="ebauthorgroup"><span class="ebauthorgroupname">'+ebook.author[i].name+'</span><ul>';
for (var j = 0; j<ebook.author[i].author.length; j++){
ebgroup += '<li>'+ebook.author[i].author[j]+'</li>';
}
ebgroup += '</ul></div>';
ebauthors.push(ebgroup);
}
}
var ebsecondaryauthors = []
for (var i = 0; i<ebook.secondaryauthor.length; i++){
if (typeof(ebook.secondaryauthor[i]) === 'string'){
ebsecondaryauthors.push('<span class="ebauthor">'+ebook.secondaryauthor[i]+'</span>');
} else {
var ebgroup = '<div class="ebauthorgroup"><span class="ebauthorgroupname">'+ebook.secondaryauthor[i].name+'</span><ul>';
for (var j = 0; j<ebook.secondaryauthor[i].author.length; j++){
ebgroup += '<li>'+ebook.secondaryauthor[i].author[j]+'</li>';
}
ebgroup += '</ul></div>';
ebsecondaryauthors.push(ebgroup);
}
}
var wikitext = '<div class="primaryauthors">'+ebauthors.join(', ')+'</div>';
if (ebsecondaryauthors.length > 0){
wikitext += '&<div class="secondaryauthors">'+ebsecondaryauthors.join('\n')+'</div>';
}
wikitext = '<html><div class="ebookauthors">\n' + wikitext + '</div></html>';
wikify(wikitext, place);
jQuery(place).find('.ebauthorgroupname').click(function(){
jQuery(this).parents('.ebauthorgroup').toggleClass('showall');
});
}
}
config.macros.ebooksitetitle = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var booktitle;
if (Emathbook.options.pages[0].lang == Emathbook.options.pages[0].defaultlang){
booktitle = EbookPages[0].ebook.title;
} else {
booktitle = EbookPages[0].ebook.alttitles[Emathbook.options.pages[0].lang] || '';
}
wikify(booktitle, place);
}
}
//}}}
/*{{{*/
/****************************** Table of contents *******************************/
.sdbooktoc {
border: 2px solid #3f4426;
background-color: #cddd7d;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-o-border-radius: 8px;
}
.sdbooktoc h1 {
font-size: 250%;
background-color: #3f4426;
color: white;
margin: 0;
padding: 1em 0.3em;
text-align: center;
border-radius: 7px 7px 0 0;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
-o-border-radius: 7px 7px 0 0;
}
.sdbooktoc h1 a {
color: #3f4426;
font-style: normal;
}
.sdbooktoc ol {
margin-left: 2em;
}
.sdbooktoc ol li {
font-size: 150%;
font-weight: bold;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
.sdbooktoc ol li ul li {
font-size: 70%;
font-weight: normal;
}
div[tags~="sdtoc"] {
max-width: 70em;
}
/**************************** Chapter ************************************/
div[tags~="sdbookchapter"] div.title {
font-size: 200%;
text-align: center;
}
div[tags~="sdbookchapter"] {
max-width: 70em;
text-align: justify;
}
/**************************** Hidden ***********************************/
.sdbookhidden {
display: none;
margin: 0;
padding: 0;
}
/**************************** Example ***********************************/
.sdbookexample {
max-width: 60em;
border: 1px solid #aaa;
background-color: white;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
padding: 0 10px 10px 10px;
margin: 2em;
}
.sdbookexample h1 {
font-size: 160%;
background-color: #e7ffb7;
color: black;
margin: 0 -10px 10px -10px;
padding: 0.4em 0.1em;
text-align: center;
border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
text-sahdow: 2px 2px 2px white;
border-bottom: 3px solid #3f4426;
}
.sdbookexample.sdclickable h1 {
cursor: pointer;
}
/**************************** Theory ***********************************/
.sdbooktheory {
max-width: 60em;
border: 1px solid #aaa;
background-color: #fffdb7;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
padding: 0 10px 10px 10px;
margin: 2em;
}
.sdbooktheory h1 {
font-size: 160%;
background-color: #ffd500;
color: black;
margin: 0 -10px 10px -10px;
padding: 0.4em 0.1em;
text-align: center;
border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
text-sahdow: 2px 2px 2px #555;
border-bottom: none;
}
/************************* sdtable ******************************************/
table.sdtable {
border-collapse: collapse;
border: none;
margin: 0;
padding: 0.3em 0;
}
.sdtable td:first-child {
min-width: 2em;
}
.sdtable tr,
.sdtable td {
border: none;
}
.sdtable td {
vertical-align: top;
}
/************************* Exercise ***********************************************/
span.sdbuttonexercise {
display: inline-block;
position: relative;
width: 330px;
height: 60px;
background: transparent url('[[button-harjoitus.png.base64]]') left top no-repeat;
}
span.sdbuttonexercise .sdbuttonlabel {
padding: 1px 8px;
border-left: 2px solid black;
border-right: 2px solid black;
border-top: 2px solid white;
border-bottom: none;
color: red;
font-weight: bold;
position: absolute;
top: 0px;
right: 15px;
}
/************************* Layout ***********************************************/
.sdcenter {
display: block;
text-align: center;
}
/*}}}*/
<<showData>>
<data>{"config":{"datatiddler":"SettingsEbook","userdatatiddler":"SettingsEbookUser","commenttiddler":"EbookComments","showcomments":true,"updateURL":"http://"},"pagetwovisible":true}</data>
<<showData>>
<data>{"ebookpages":{"pageOne":{"emptybook":{"currentpage":"front","lang":"fi"},"currentpage":"front","bookid":"emptybook"},"pageTwo":{"emptybook":{"currentpage":"front","lang":"fi"},"currentpage":"front","bookid":"emptybook"}},"pagetwovisible":false,"updates":{"lastCheck":"","lastSysCheck":"2014-01-09 14:48:35","lastChecks":{}},"datatiddler":"SettingsEbookUser","commenttiddler":"EbookComments","ebooktheme":"default","showstepbystep":false,"mqpanelautoshowhide":true,"mqpanelforceshow":false,"pagecomments":{"lastCheck":{}},"coursecomments":{"lastCheck":{}},"eulexiafontuse":false}</data>
<<showData>>
<data>{"lang": "fi"}</data>
<<tiddler [[emquiz_triangle]]>>
----
<<tiddler [[10_ebook_assignmentlist_1]]>>
----
<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">><<attach>>
/%
<<tabs sidebartabs
"Egen pick-ups" "Egen pick-ups" [[EbookOwnPickups]]
"Uppgifter" "Uppgifter" [[EbookAssignments]]
>>
%/
/%
!{{head{Egen pick-ups}}}
%/
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.7|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Show tiddlers one at a time with automatic permalink, or always open tiddlers at top/bottom of page.|
This plugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one tiddler displayed at a time.
!!!!!Documentation
>see [[SinglePageModePluginInfo]]
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)
Notes:
* The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}.
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2010.11.30 2.9.7 use story.getTiddler()
2008.10.17 2.9.6 changed chkSinglePageAutoScroll default to false
| Please see [[SinglePageModePluginInfo]] for previous revision details |
2005.08.15 1.0.0 Initial Release. Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts.
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageModePlugin= {major: 2, minor: 9, revision: 7, date: new Date(2010,11,30)};
//}}}
//{{{
config.paramifiers.SPM = { onstart: function(v) {
config.options.chkSinglePageMode=eval(v);
if (config.options.chkSinglePageMode && config.options.chkSinglePagePermalink && !config.browser.isSafari) {
config.lastURL = window.location.hash;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
} };
//}}}
//{{{
if (config.options.chkSinglePageMode==undefined)
config.options.chkSinglePageMode=false;
if (config.options.chkSinglePagePermalink==undefined)
config.options.chkSinglePagePermalink=true;
if (config.options.chkSinglePageKeepFoldedTiddlers==undefined)
config.options.chkSinglePageKeepFoldedTiddlers=false;
if (config.options.chkSinglePageKeepEditedTiddlers==undefined)
config.options.chkSinglePageKeepEditedTiddlers=false;
if (config.options.chkTopOfPageMode==undefined)
config.options.chkTopOfPageMode=false;
if (config.options.chkBottomOfPageMode==undefined)
config.options.chkBottomOfPageMode=false;
if (config.options.chkSinglePageAutoScroll==undefined)
config.options.chkSinglePageAutoScroll=false;
//}}}
//{{{
config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
if (!config.options.chkSinglePageMode)
{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
if (config.lastURL == window.location.hash) return; // no change in hash
var tids=decodeURIComponent(window.location.hash.substr(1)).readBracketedList();
if (tids.length==1) // permalink (single tiddler in URL)
story.displayTiddler(null,tids[0]);
else { // restore permaview or default view
config.lastURL = window.location.hash;
if (!tids.length) tids=store.getTiddlerText("DefaultTiddlers").readBracketedList();
story.closeAllTiddlers();
story.displayTiddlers(null,tids);
}
}
if (Story.prototype.SPM_coreDisplayTiddler==undefined)
Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
var tiddlerElem=story.getTiddler(title); // ==null unless tiddler is already displayed
var opt=config.options;
var single=opt.chkSinglePageMode && !startingUp;
var top=opt.chkTopOfPageMode && !startingUp;
var bottom=opt.chkBottomOfPageMode && !startingUp;
if (single) {
story.forEachTiddler(function(tid,elem) {
// skip current tiddler and, optionally, tiddlers that are folded.
if ( tid==title
|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
return;
// if a tiddler is being edited, ask before closing
if (elem.getAttribute("dirty")=="true") {
if (opt.chkSinglePageKeepEditedTiddlers) return;
// if tiddler to be displayed is already shown, then leave active tiddler editor as is
// (occurs when switching between view and edit modes)
if (tiddlerElem) return;
// otherwise, ask for permission
var msg="'"+tid+"' is currently being edited.\n\n";
msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
if (!confirm(msg)) return; else story.saveTiddler(tid);
}
story.closeTiddler(tid);
});
}
else if (top)
arguments[0]=null;
else if (bottom)
arguments[0]="bottom";
if (single && opt.chkSinglePagePermalink && !config.browser.isSafari) {
window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));
config.lastURL = window.location.hash;
document.title = wikifyPlain("SiteTitle") + " - " + title;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
var isTopTiddler=(tiddlerElem.previousSibling==null);
if (!isTopTiddler && (single || top))
tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
else if (bottom)
tiddlerElem.parentNode.insertBefore(tiddlerElem,null);
else this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
} else
this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
var tiddlerElem=story.getTiddler(title);
if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
// scroll to top of page or top of tiddler
var isTopTiddler=(tiddlerElem.previousSibling==null);
var yPos=isTopTiddler?0:ensureVisible(tiddlerElem);
// if animating, defer scroll until after animation completes
var delay=opt.chkAnimate?config.animDuration+10:0;
setTimeout("window.scrollTo(0,"+yPos+")",delay);
// Added by pesasa for sdebook
setTimeout("document.getElementById('displayArea').scrollTop = 0",delay);
}
}
if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function() {
// suspend single/top/bottom modes when showing multiple tiddlers
var opt=config.options;
var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
this.SPM_coreDisplayTiddlers.apply(this,arguments);
opt.chkBottomOfPageMode=saveBPM;
opt.chkTopOfPageMode=saveTPM;
opt.chkSinglePageMode=saveSPM;
}
//}}}
/***
|Name|SinglePageModePluginInfo|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|Documentation for SinglePageModePlugin|
Normally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing. SinglePageModePlugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time.
!!!!!Usage
<<<
When the plugin is enabled, only one tiddler will be displayed at a time and the browser window's titlebar is updated to include the current tiddler title. The browser's location URL is also updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler. Alternatively, even when displaying multiple tiddlers //is// permitted, you can still reduce the potential for confusion by forcing tiddlers to always open at the top (or bottom) of the page instead of being displayed following the tiddler containing the link that was clicked.
<<<
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)
Notes:
* {{block{
The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}. You can also use {{{SPM:expression}}}, where 'expression' is any javascript statement that evaluates to true or false. This allows you to create hard-coded links in other documents that can selectively enable/disable the use of this option based on various programmatic conditions, such as the current username. For example, using
{{{#SPM:config.options.txtUserName!="SomeName"}}}
enables 'one tiddler at a time' display for all users //other than// "~SomeName")}}}
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2008.10.17 2.9.6 changed chkSinglePageAutoScroll default to false
2008.06.12 2.9.5 corrected 'scroll to top of page' logic in auto-scroll handling
2008.06.11 2.9.4 added chkSinglePageKeepEditedTiddlers option
2008.06.05 2.9.3 in displayTiddler(), bypass single/top/bottom mode handling if startingUp. Allows multiple tiddlers to be displayed during startup processing (e.g., #story:DefaultTiddlers), even if single/top/bottom mode is enabled.
2008.04.18 2.9.2 in displayTiddler() and checkLastURL(), handling for Unicode in tiddler titles (remove explicit conversion between Unicode and UTF, as this is apparently done automatically by encode/decodeURIComponent, resulting in double-encoding!
2008.04.08 2.9.1 don't automatically add options to AdvancedOptions shadow tiddler
2008.04.02 2.9.0 in displayTiddler(), when single-page mode is in use and a tiddler is being edited, ask for permission to save-and-close that tiddler, instead of just leaving it open.
2008.03.29 2.8.3 in displayTiddler(), get title from tiddler object (if needed). Fixes errors caused when calling function passes a tiddler *object* instead of a tiddler *title*
2008.03.14 2.8.2 in displayTiddler(), if editing specified tiddler, just move it to top/bottom of story *without* re-rendering (prevents discard of partial edits).
2008.03.06 2.8.1 in paramifier handler, start 'checkURL' timer if chkSinglePageMode is enabled
2008.03.06 2.8.0 added option, {{{config.options.chkSinglePageKeepFoldedTiddlers}}}, so folded tiddlers won't be closed when using single-page mode. Also, in checkURL(), if hash is a ''permaview'' (e.g., "#foo bar baz"), then display multiple tiddlers rather than attempting to display "foo bar baz" as a single tiddler
2008.03.05 2.7.0 added support for "SPM:" URL paramifier
2008.03.01 2.6.0 in hijack of displayTiddler(), added 'title' argument to closeAllTiddlers() so that target tiddler isn't closed-and-reopened if it was already displayed. Also, added config.options.chkSinglePageAutoScrolloption to bypass automatic 'scroll into view' logic (note: core still does it's own ensureVisible() handling)
2007.12.22 2.5.3 in checkLastURL(), use decodeURIComponent() instead of decodeURI so that tiddler titles with commas (and/or other punctuation) are correctly handled.
2007.10.26 2.5.2 documentation cleanup
2007.10.08 2.5.1 in displayTiddler(), when using single-page or top-of-page mode, scrollTo(0,0) to ensure that page header is in view.
2007.09.13 2.5.0 for TPM/BPM modes, don't force tiddler to redisplay if already shown. Allows transition between view/edit or collapsed/view templates, without repositioning displayed tiddler.
2007.09.12 2.4.0 added option to disable automatic permalink feature. Also, Safari is now excluded from permalinking action to avoid bug where tiddlers don't display after hash is updated.
2007.03.03 2.3.1 fix typo when adding BPM option to AdvancedOptions (prevented checkbox from appearing)
2007.03.03 2.3.0 added support for BottomOfPageMode (BPM) based on request from DaveGarbutt
2007.02.06 2.2.3 in Story.prototype.displayTiddler(), use convertUnicodeToUTF8() for correct I18N string handling when creating URL hash string from tiddler title (based on bug report from BidiX)
2007.01.08 2.2.2 use apply() to invoke hijacked core functions
2006.07.04 2.2.1 in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.
2006.06.01 2.2.0 added chkTopOfPageMode (TPM) handling
2006.02.04 2.1.1 moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals
2005.12.27 2.1.0 hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list). Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers
2005.12.27 2.0.0 Update for TW2.0
2005.11.24 1.1.2 When the back and forward buttons are used, the page now changes to match the URL. Based on code added by Clint Checketts
2005.10.14 1.1.1 permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them
2005.10.14 1.1.0 added automatic setting of window title and location bar ('auto-permalink'). feature suggestion by David Dickens.
2005.10.09 1.0.1 combined documentation and code in a single tiddler
2005.08.15 1.0.0 Initial Release
<<<
//{{{
/*******************************************************************
* solutions.js
* Student functionality for TiddlyWiki-ebook
* Petri Salmela
* Petri Sallasmaa
* 31.05.2012
*******************************************************************/
/***********************************************
* EbSolutionElement -class
* One solution element (text, structured derivation,...)
***********************************************/
EbSolutionElement = function(options, editable){
options = options || {};
this.type = options.type || 'text';
this.data = options.data || '';
this.editable = !!editable;
}
EbSolutionElement.prototype.getWiki = function(){
var wikitext = '{{solutionelement{\n';
var iseditable = '';
if (this.editable){
iseditable = ' edit';
}
try{
wikitext += this['getWiki'+this.type](this.data,iseditable );
}catch(e){
wikitext += 'error '+e;
}
wikitext += '}}}';
return wikitext;
}
EbSolutionElement.prototype.getData = function(){
return {"type": this.type, "data": this.data};
}
/***********************************************
* EbSolution -class
* One solution which is ordered set of solution elements + answer
***********************************************/
EbSolution = function(options){
options = options || {};
this.tiddlerName = options.tiddlerName || '';
this.place = jQuery(options.place) || jQuery('<div></div>');
this.editable = !!options.editable;
this.assignment = options.assignment || '';
this.elements = [];
this.answer = '';
this.creator = '';
this.ispublic = false;
}
EbSolution.prototype.initElements = function(){
var solutiondata = DataTiddler.getData(this.tiddlerName, "solution", {"creator":"","solutionelements":[], "answer":"", "editable": true, "ispublic":false});
this.creator = solutiondata.creator || config.options.txtUserName;
this.answer = solutiondata.answer || '';
this.editable = !!solutiondata.editable;
this.ispublic = !!solutiondata.ispublic;
var elements = solutiondata.solutionelements || [];
for (var i = 0; i < elements.length; i++){
var elem = new EbSolutionElement(elements[i], this.editable);
this.addElement(elem);
}
}
EbSolution.prototype.save = function(){
var solutiondata = {
"creator": this.creator,
"answer": this.answer,
"editable": this.editable,
"ispublic": this.ispublic,
"solutionelements": []
}
for (var i = 0; i < this.elements.length; i++){
solutiondata.solutionelements.push(this.elements[i].getData());
}
DataTiddler.setData(this.tiddlerName, 'solution', solutiondata);
}
EbSolution.prototype.addElement = function(element){
this.elements.push(element);
}
EbSolution.prototype.removeElement = function(index){
this.elements.splice(index, 1);
this.save();
}
EbSolution.prototype.getWiki = function(){
var wikitext = '{{solutionset{\n';
for (var i = 0; i<this.elements.length; i++){
wikitext += this.elements[i].getWiki();
}
var pagenum = jQuery('.bookpage').index(this.place.parents('.bookpage'));
pagenum = (pagenum == -1) ? false : pagenum;
wikitext += '{{solutionanswer{\n'+EbookDictionary.localize('answer', pagenum)+'{{solutionanswerbox{'+this.answer+'}}} }}} }}}';
return wikitext;
}
EbSolution.prototype.show = function(){
var solution = this;
var pagenum = jQuery('.bookpage').index(this.place.parents('.bookpage'));
var tiddlername = this.tiddlerName;
this.place.empty();
wikify(this.getWiki(), this.place[0], null, store.getTiddler(this.tiddlerName));
if (!this.editable){
this.place.find('.solutionset:last a.button.command_qededit').remove();
var tablist = this.place.parents('.solutioncontent').prev().find('.solutiontablist');
if (tablist.length > 0 && tablist.find('li.editable').length == 0 && typeof(Teachertool) =="undefined"){
this.place.prepend('<div class="solutionedittoolbar solutioncontrolbar"><button class="editsolution">'+EbookDictionary.localize('editsolution',pagenum)+'</button></div>');
this.place.append('<div class="solutionedittoolbar solutioncontrolbar"><button class="editsolution">'+EbookDictionary.localize('editsolution',pagenum)+'</button></div>');
this.place.find('.editsolution').click(function(){
var assignmentdiv = jQuery(this).parents('.assigmentSolution');
var assignment = assignmentdiv.attr('tiddler');
Emathbook.createSolution(assignment, store.getTiddlerText(solution.tiddlerName).replace('"editable":false','"editable":true').replace('"ispublic":true','"ispublic":false'));
var htmlplace = assignmentdiv[0];
assignmentdiv.empty();
wikify('<<showSolution>>', htmlplace, null, store.getTiddler(solution.tiddlerName));
}).button();
} else if (typeof(Teachertool) =="function"){
//TÄMÄ funktioon ja teachertools.js:ään
this.place.prepend('<div class="solutionTeachertoolbar solutioncontrolbar"><button class="markSolution">'+/*EbookDictionary.localize('editsolution',pagenum)*/'Evaluate'+'</button><button class="makeModelsolution">'+/*EbookDictionary.localize('editsolution',pagenum)*/'Modelsolution'+'</button></div>');
this.place.append('<div class="solutionTeachertoolbar solutioncontrolbar"><button class="markSolution">'+/*EbookDictionary.localize('editsolution',pagenum)*/'Evaluate'+'</button><button class="makeModelsolution">'+/*EbookDictionary.localize('editsolution',pagenum)*/'Modelsolution'+'</button></div>');
this.place.find('.markSolution').click(function(){
var ttool = new Teachertool(jQuery(this).parents('.solutioncontent [tiddler]'));
ttool.startAuthoring('evaluation');
}).button();
this.place.find('.makeModelsolution').click(function(){
if(confirm("Make modelsolution from student's solution")){
var ttool = new Teachertool(jQuery(this).parents('.solutioncontent [tiddler]'));
ttool.startAuthoring('converttomodelsolution');
}
}).button();
//TÄHÄN ASTI
} else {
this.place.prepend('<div class="solutioncontrolbar"></div>');
this.place.append('<div class="solutioncontrolbar"></div>');
}
} else {
this.place.find('.solutionanswer .solutionanswerbox').mathquill('textbox').mathquill('latex', this.answer).blur()
.focusout(function(){
solution.answer = jQuery(this).mathquill('latex');
solution.save();
});
var edata = {"tiddler": this.tiddlerName};
this.place.find('.solutionset:last .solutionelement').append('<div class="removesolelem"><a href="javascript:;">X</a></div>');
this.place.find('.solutionset:last .solutionelement .removesolelem a').click(edata, function(){
var index = solution.place.find('.solutionset:last .solutionelement').index(jQuery(this).parents('.solutionelement'));
if (confirm(EbookDictionary.localize('areyousure'))){
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
solution.removeElement(index);
config.options.chkAutoSave = autosaveStatus;
solution.show();
}
});
var solutionButtons = [];//TODO:Add here 'get buttons from assignment' || []
if(solutionButtons.length ==0){
var solutionElementsToAddInittiddlers = store.getTaggedTiddlers('solutionAddElement');
for(var i=0;i<solutionElementsToAddInittiddlers.length;i++){
solutionButtons.push(solutionElementsToAddInittiddlers[i].data('addElement'));
}
}
var solutionsToolbar = this.place.find('.solutionanswer').before('<div class="solutiontoolbar"></div>').parent().find('div.solutiontoolbar');
for(var i=0;i<solutionButtons.length;i++){
if(typeof(solution[solutionButtons[i].addFuction])=="function"){
solutionsToolbar.append('<button buttonListNro="'+i+'" class="add'+solutionButtons[i].elementType+'">+'+EbookDictionary.localize(solutionButtons[i].elementType,pagenum)+'</button>').find('.add'+solutionButtons[i].elementType).click(function(){
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
solution[solutionButtons[jQuery(this).attr('buttonListNro')].addFuction]();
config.options.chkAutoSave = autosaveStatus;
solution.show();
}).button();
}
}
this.place.prepend('<div class="solutionsendtoolbar solutioncontrolbar"><button class="ordersolutions">'+EbookDictionary.localize('order',pagenum)+'</button><button class="orderready">'+EbookDictionary.localize('ready',pagenum)+'</button><button class="ordercancel">'+EbookDictionary.localize('cancel',pagenum)+'</button><button class="savesolution">'+EbookDictionary.localize('save',pagenum)+'</button><button class="sendsolution">'+EbookDictionary.localize('send',pagenum)+'</button></div>');
this.place.append('<div class="solutionsendtoolbar solutioncontrolbar"><button class="ordersolutions">'+EbookDictionary.localize('order',pagenum)+'</button><button class="orderready">'+EbookDictionary.localize('save',pagenum)+'</button><button class="ordercancel">'+EbookDictionary.localize('cancel',pagenum)+'</button><button class="savesolution">'+EbookDictionary.localize('save',pagenum)+'</button><button class="sendsolution">'+EbookDictionary.localize('send',pagenum)+'</button></div>');
this.place.find('.sendsolution').click(function(){
var defaultlang = Emathbook.options.pages[pagenum]["defaultlang"];
var pagelang = Emathbook.options.pages[pagenum].lang;
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(store.getTiddler(tiddlername).fields.solutionto+'_'+pagelang)){
solutionAnswer = store.getTiddler(store.getTiddler(tiddlername).fields.solutionto+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(store.getTiddler(tiddlername).fields.solutionto).data('assignmentSolution',"");
}
if(solutionAnswer !=="" && solution.place.parents('div.assigmentSolution').siblings('.assignmentSolution.solutionAnswer').length === 0){
var assignmentSolutionPlace = solution.place.parents('div.assigmentSolution').after('<div class="assignmentSolution solutionAnswer"></div>').next();
wikify(solutionAnswer,assignmentSolutionPlace[0]);
}
solution.editable = false;
solution.ispublic = true;
solution.save();
var sendData = {'type':'5','tiddlerName':tiddlername,'isPublic':1};
Emathbook.getCourseUpdatesSilent(sendData);
jQuery(this).parents('.solutioncontent').prev().find('li.currenttab').removeClass('editable').find('a').click();
}).button();
this.place.find('button.ordersolutions').click(function(){
solution.place.addClass('solsortable')
.find('.solutionset').sortable({placeholder: "ui-state-highlight"})
.find('.solutionelement').append('<div class="ordershade"></div>')
.each(function(index){
jQuery(this).attr('solutionelemname', solution.elements[index].data)
.attr('solutionelemtype', solution.elements[index].type);
});
}).button();
this.place.find('button.orderready').click(function(){
solution.place.removeClass('solsortable')
.find('div.solutionset').sortable('destroy')
.find('div.ordershade').remove();
var elementlist = solution.place.find('div.solutionelement').map(function(){
var soldata = jQuery(this).attr('solutionelemname');
var soltype = jQuery(this).attr('solutionelemtype');
return new EbSolutionElement({"type": soltype, "data": soldata}, true);
}).toArray();
solution.elements = elementlist;
solution.save();
}).button();
this.place.find('button.ordercancel').click(function(){
solution.place.removeClass('solsortable');
solution.show();
}).button();
this.place.find('button.savesolution').click(function(){
var savedTiddler =store.getTiddler(tiddlername);
savedTiddler.tags.pushUnique('backupthis');
savedTiddler.set(savedTiddler.title);
solution.save();
}).button();
}
this.place.find('.solutioncontrolbar').append('<button class="emath_printpreview">'+EbookDictionary.localize('preview')+'</button>')
.find('.emath_printpreview').click(function(){
Emathbook.print(this, 'solution');
return false;
}).button({
icons: {primary: 'emui-icon-preview'},
text: false
});
}
config.macros.ebooksolution = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var sol = tiddler.data('solution', {"creator":"","solutionelements":[]});
var editable = (sol.creator == config.options.txtUserName) && sol.editable;
jQuery(place).append('<div class="solutionsetwrapper"></div>');
place = jQuery(place).find('.solutionsetwrapper:last')[0];
var solution = new EbSolution({"tiddlerName":tiddler.title, "place": place, "editable":editable});
solution.initElements();
solution.show();
jQuery(place).find('.solutionanswerbox.mathquill-editable').last().blur();
jQuery(place).find('.mathquill-editable').first().focus();
}
}
/*************************************************
* Teacher's marking tool
*************************************************/
SdMarkingMessage = function(options){
// Class for one marking and comment of structured derivation.
this.loc = (options && options.loc) || '';
this.mark = (options && options.mark) || '';
this.comment = (options && options.comment) || '';
return this;
}
SdMarkingMessage.prototype.setLoc = function(location){
this.loc = location;
}
SdMarkingMessage.prototype.setMark = function(mark){
this.mark = mark;
}
SdMarkingMessage.prototype.setComment = function(comment){
this.comment = comment;
}
SdMarkingMessage.prototype.getLoc = function(){
return this.loc;
}
SdMarkingMessage.prototype.getMark = function(){
return this.mark;
}
SdMarkingMessage.prototype.getComment = function(){
return this.comment;
}
SdMarkingMessage.prototype.getObject = function(){
var obj = {
"loc": this.loc,
"mark": this.mark,
"comment": this.comment
}
return obj;
}
SdMarkingMessage.prototype.getJson = function(){
var obj = this.getObject();
return JSON.stringify(obj);
}
SdMarkings = function(options){
// Class for set of markings and comments (SdMarkingMessage elements) plus general comment
this.messages = {};
if (options && options.messages && options.messages.length > 0){
for (var i = 0; i < options.messages.length; i++){
var message = new SdMarkingMessage(options.messages[i]);
this.messages[message.getLoc()] = message;
}
}
this.general = (options && options.general) || '';
this.markingsto = (options && options.markingsto) || '';
this.tiddlername = (options && options.tiddler) || false;
return this;
}
SdMarkings.checkmarks = {"correct": "✔", "wrong": "✘", "note": "!", "empty": "?", "finnishcorrect":"⁒"};
SdMarkings.prototype.addMessage = function(options){
if (!options){
options = {"loc":"","mark":"","comment":""};
}
var message = new SdMarkingMessage(options);
this.messages[message.getLoc()] = message;
return this;
}
SdMarkings.prototype.messageExists = function(loc){
return !!this.messages[loc];
}
SdMarkings.prototype.getMessage = function(loc){
return (this.messages[loc] || false);
}
SdMarkings.prototype.getLoc = function(loc){
return (this.messages[loc] && this.messages[loc].loc) || '';
}
SdMarkings.prototype.getMark = function(loc){
return (this.messages[loc] && this.messages[loc].mark) || '';
}
SdMarkings.prototype.getComment = function(loc){
return (this.messages[loc] && this.messages[loc].comment) || '';
}
SdMarkings.prototype.setGeneral = function(general){
this.general = general;
return this;
}
SdMarkings.prototype.getGeneral = function(){
return this.general;
}
SdMarkings.prototype.getObject = function(){
var obj = {
"general": this.general,
"messages": []
};
for (var key in this.messages){
obj.messages.push(this.messages[key].getObject());
}
return obj;
}
SdMarkings.prototype.save = function(){
if (this.tiddlername){
DataTiddler.setData(this.tiddlername, 'sdmarkings', this.getObject());
var tiddler = store.getTiddler(this.tiddlername);
tiddler.fields.markingsto = this.markingsto;
tiddler.set(tiddler.title, null, null, new Date(), null, null, tiddler.fields);
return true;
} else {
return false;
}
}
SdMarkings.prototype.read = function(tiddler){
if (typeof(tiddler) != 'undefined'){
this.tiddlername = tiddler;
}
if (typeof(this.tiddlername) != 'undefined'){
var data = DataTiddler.getData(this.tiddlername, 'sdmarkings', {"general":"","markings":[]});
if (typeof(data.messages) == 'undefined' || typeof(data.messages.length) == 'undefined'){
data.messages = [];
}
this.general = data.general;
this.markingsto = (store.tiddlerExists(this.tiddlername) && store.getTiddler(this.tiddlername).fields.markingsto) || '';
for (var i = 0; i < data.messages.length; i++){
this.addMessage(data.messages[i]);
}
}
}
SdMarkings.prototype.show = function(place){
if (typeof(place) != 'undefined'){
this.place = jQuery(place);
} else {
this.place = jQuery('[tiddler="'+this.markingsto + '"]').last();
}
if (this.place.length > 0){
this.place.find('td .sdafterbuttons').empty();
for (var key in this.messages){
if (this.messages[key].mark !== 'empty'){
this.place.find('td[loc="'+this.messages[key].loc + '"]')
.find('.sdafterbuttons').empty()
.append('<div class="manualcheck"><span class="checkmark sd'+this.messages[key].mark+'"><span>'
+ SdMarkings.checkmarks[this.messages[key].mark] + '</span></span><span class="checkcomment">'
+ this.messages[key].comment.replace(/\\\(/g,'<span class="mathquill-embedded-latex">')
.replace(/\\\)/g,'</span>') + '</span></div>')
.show()
.find('.mathquill-embedded-latex:not(.mathquill-rendered-math)')
.mathquill('embedded-latex')
.end()
.mouseenter(function(){
jQuery(this).find('.mathquill-embedded-latex').mathquill('redraw');
});
}
}
this.place.find('.generalfeedback').remove();
this.place.find('.solutionanswerbox').after('<div class="generalfeedback"></div>')
.next().append('<p>'+this.getGeneral()
.replace(/\\\(/g,'<span class="mathquill-embedded-latex">')
.replace(/\\\)/g,'</span>')
.replace(/\$([^$]+)\$/g,'<span class="mathquill-embedded-latex">$1</span>') + '</p>')
.find('.mathquill-embedded-latex:not(.mathquill-rendered-math)')
.mathquill('embedded-latex');
}
return this;
}
SdMarkings.prototype.edit = function(place){
if (typeof(place) != 'undefined'){
this.place = jQuery(place);
} else {
this.place = jQuery('[tiddler="'+this.markingsto + '"]');
}
var markings = this;
if (this.place.length > 0){
var sdafterbuttons = this.place.find('.sdafterbuttons');
for (var i = 0; i < sdafterbuttons.length; i++){
sdafterbuttons.eq(i).empty().show().append('<div class="sdmanualcheckbox"><span class="sdcorrectionmarks"><span class="sdcorrect" title="Correct"><span>'+SdMarkings.checkmarks['correct']+'</span></span><span class="sdwrong" title="Wrong"><span>'+SdMarkings.checkmarks['wrong']+'</span></span><span class="sdnote" title="Note"><span>'+SdMarkings.checkmarks['note']+'</span></span><span class="sdempty selected" title="Remove comment"><span>'+SdMarkings.checkmarks['empty']+'</span></span></span><input type="text" class="sdmanualcheckcomment" /><button class="sdmanualcheckready">OK</button></div>')
.find('.sdmanualcheckbox').click(function(){
jQuery(this).addClass('sdactive');
})
.find('button.sdmanualcheckready').click(function(){
jQuery(this).parents('.sdactive').eq(0).removeClass('sdactive');
var thisloc = jQuery(this).parents('td').eq(0).attr('loc');
var thismark = jQuery(this).parent().find('.selected').attr('class');
thismark=thismark.replace(/(s[a-z]*d|\s)/g,'');
var thiscomment= jQuery(this).parent().find('input').val();
markings.addMessage({'loc':thisloc,'mark':thismark,'comment':thiscomment});
return false;
}).end()
.find('.sdcorrectionmarks span').click(function(){
jQuery(this).parent().find('.selected').removeClass('selected');
jQuery(this).addClass('selected');
if (jQuery(this).hasClass('sdempty')){
jQuery(this).parents('.sdmanualcheckbox').find('input').addClass('hideinput');
} else {
jQuery(this).parents('.sdmanualcheckbox').find('input').removeClass('hideinput');
}
});
var elementlocation = sdafterbuttons.eq(i).parent().attr('loc');
if (this.getMessage(elementlocation)){
sdafterbuttons.eq(i).find('.sdmanualcheckbox input').val(this.getComment(elementlocation));
sdafterbuttons.eq(i).find('.sdmanualcheckbox .selected').removeClass('selected');
if (this.getMark(elementlocation)=="correct"){
sdafterbuttons.eq(i).find('.sdmanualcheckbox .sdcorrect').addClass('selected');
}else if (this.getMark(elementlocation)=="wrong"){
sdafterbuttons.eq(i).find('.sdmanualcheckbox .sdwrong').addClass('selected');
}else if (this.getMark(elementlocation)=="note"){
sdafterbuttons.eq(i).find('.sdmanualcheckbox .sdnote').addClass('selected');
}else {
sdafterbuttons.eq(i).find('.sdmanualcheckbox .sdempty').addClass('selected');
}
}
}
this.place.find('.generalfeedback').remove();
this.place.find('.solutionanswerbox').after('<div class="generalfeedback"><span class="generalfeedbacktext mathquill-textbox">'+this.getGeneral()+'</span></div>');
var generalfeedbacktext = this.place.find('.generalfeedbacktext');
generalfeedbacktext.mathquill('textbox').focusout(function(){
markings.setGeneral(jQuery(this).mathquill('latex'));
});
}
}
//}}}
/*{{{*/
[[StyleSheetSdtable]]
[[StyleSheetOwnColors]]
[[StyleSheetOwnLayout]]
[[StyleSheetEbookLayout]]
[[StyleSheetEbookAuthor]]
[[StyleSheetEbookDefaultTheme]]
[[StyleSheetEbookPrint]]
[[StyleSheetQedEditor]]
/*}}}*/
/***
|''Name:''|StyleSheetEbookAuthor|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Ebook styles for athorbooks|
|''Version:''|1.3|
|''Date:''|September 16, 2013|
|''Contact:''|pesasa@iki.fi|
|''Documentation:''| |
!!!!!Revisions
<<<
20131213.1508 //v.1.4// ''added:'' modelsolutionlist show/hide
<<<
<<<
20131210.13.57 //v.1.3// ''added:'' Book toc editor headimageselector styles
<<<
<<<
20131203.14.31 //v.1.2// ''added:'' Book toc editor styles
<<<
<<<
20130919.12.31 //v.1.1// ''added:'' coursecommentapp styles
<<<
<<<
20130916.14.30 //v.1.0// ''Created''
<<<
!!!!!Code
***/
/*{{{*/
/************************************
* Styles for authorbooks
* Petri Salmela
* 16.9.2013
************************************/
/********************
* Author mode
********************/
#actionButtons {
z-index: 600;
}
/**************************************
* Author modelsolutionlist show/hide
*************************************/
.bookpage .sdbookassignmentlist .modelsolutionlist.listhidden .solutiontabs,
.bookpage .sdbookassignmentlist .modelsolutionlist.listhidden .solutioncontent
{
display:none;
}
.bookpage .sdbookassignmentlist .modelsolutionlist.listhidden h3 .hidelist,
.bookpage .sdbookassignmentlist .modelsolutionlist h3 .showlist
{
display:none;
}
.bookpage .sdbookassignmentlist .modelsolutionlist h3 .listvisibility{
font-size:70%;
float:right;
border:1px solid green;
border-radius:5px;
padding:0.2em 0.5em;
background-color:white;
color:black;
cursor:pointer;
}
.bookpage .sdbookassignmentlist .modelsolutionlist h3 .hidelist,
.bookpage .sdbookassignmentlist .modelsolutionlist.listhidden h3 .showlist
{
display:inline-block;
}
/********************
* Book toc editor
********************/
#tocStructureEdit{
padding-top:60px;
padding-bottom:50px;
margin-top:0;
background-color:white;
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
z-index:1001;
}
#tocStructureEdit .emtocapp-wrapper .emtoc-header span.canceltocedit svg{
margin-top:-1px;
margin-left:-2px;
}
#tocStructureEdit .emtocapp-wrapper .emtoc-header span.toceditinfo svg,
#tocStructureEdit .emtocapp-wrapper .emtoc-header span.savetocedit svg{
margin-top:-1px;
margin-left:-3px;
}
#tocStructureEdit .emtocapp-wrapper .emtoc-headbar .emtoc-buttonbar {
margin-top:0;
}
#tocStructureEdit .tocEditor {
margin:0;
}
#tocStructureEdit .tocEditor .emtoc-header .emtocapp-wrapper h1.emtoc-title{
padding:0.5em 0.3em 0.1em 0.3em;
margin-left:1em;
}
#tocStructureEdit .tocEditor .emtoc-header
{
position:fixed;
top:0;
left:0;
width:100%;
background-color:#FFF;
}
#tocStructureEdit .tocEditor ul ul:after
{
padding : 0 6em;
content:"+";
background-color:#0b0;
color:white;
font-weight:bold;
border:1px solid #888;
border-radius:4px;
}
#tocStructureEdit .tocEditor ul ul ul:after
{
padding : 0 4em;
background-color:#090;
}
#tocStructureEdit .tocEditor ul ul ul ul:after
{
padding : 0 2em;
background-color:#070;
}
#tocStructureEdit .theory{width:10px; height:10px; border:1px solid black;background-color:yellow;display:inline-block;margin-right:3px;margin-left:3px;}
#tocStructureEdit .example{width:10px; height:10px; border:1px solid black;background-color:green;display:inline-block;margin-right:3px;margin-left:3px;}
#tocStructureEdit .noheader{width:10px; height:10px; border:1px solid black;background-color:black;display:inline-block;margin-right:3px;margin-left:3px;}
#tocStructureEdit .topic{width:10px; height:10px; border:1px solid black;background-color:red;display:inline-block;margin-right:3px;margin-left:3px;}
#tocStructureEdit .extramaterial{width:10px; height:10px; border:1px solid blue;background-color:cyan;display:inline-block;margin-right:3px;margin-left:3px;}
#tocStructureEdit .frontpage{width:10px; height:10px; border:1px solid black;background-color:pink;display:inline-block;margin-right:3px;}
#tocStructureEdit .chapter{width:10px; height:10px; border:1px solid #555;background-color:#555;display:inline-block;margin-right:3px;}
#tocStructureEdit .section{width:10px; height:10px; border:1px solid #999;background-color:#999;display:inline-block;margin-right:3px;}
#tocStructureEdit .assignments{width:10px; height:10px; border:1px solid orange;background-color:orange;display:inline-block;margin-right:3px;}
#tocStructureEdit .text{width:10px; height:10px; border:1px solid #FFDEAD;background-color:#FFDEAD;display:inline-block;margin-right:3px;}
#booktitleedit{
color:blue;
cursor:pointer;
}
#itemdialog .subTypes .fillMeMessage{
text-align:right;
visibility:hidden;
color:red;
}
#itemdialog .subTypes.fillMe .fillMeMessage{
visibility:visible;
}
#itemdialog .subTypes.fillMe{
border:1px solid red;
border-radius:0 7px;
}
#bookAuthors{display:inline-block;}
#bookSecAuthors{display:inline-block;}
#bookAuthors{vertical-align:top;}
#bookAuthors{margin-right:1em;}
#bookAuthors ul,
#bookSecAuthors ul{
list-style:none;
}
#bookAuthors ul,
#bookSecAuthors ul
{
margin: 0px;
padding: 0px;
}
#bookAuthors ul:after,
#bookSecAuthors ul:after
{
padding : 0 5em;
content:"+";
background-color:#0b0;
color:white;
font-weight:bold;
border:1px solid #888;
border-radius:4px;
cursor:pointer;
}
#bookSecAuthors ul ul:after
{
padding : 0 4em;
margin-left:2em;
background-color:#070;
cursor:pointer;
}
#bookSecAuthors ul ul
{
border:1px solid #070;
border-radius:0 0 8px 8px;
}
#bookSecAuthors ul > li > ul > li{padding-left:2em;}
#bookAuthors ul > li,
#bookSecAuthors ul > li
{
text-align:left;
padding-bottom:0.2em;
padding-top:0.3em;
}
#bookAuthors .removeAuthor,
#bookSecAuthors .removeSecAuthor,
#bookSecAuthors .removeSecgroup
{
background-color:red;
border:1px solid black;
padding:0 4px 3px 4px;
border-radius:10px;
color:white;
font-weight:bold;
margin-left:2px;
margin-bottom:2px;
cursor:pointer;
}
#bookSecAuthors span.removeSecgroup{
margin-left:-20px;
background-color:orange;
position:absolute;
float:rigth;
}
#booksettingsdialog .bookTitle input[name="currentTitle"]
{
display:block;
width:100%;
}
#bookSecAuthors .authorgroups input.groupname
{
display:inline-block;
width:100%;
}
#tocinfobox{
display:none;
}
#tocinfobox .closeTocinfo{
float:right;
}
#tocinfobox.shown{
display:block;
border:1px solid #333;
box-shadow:3px 3px 3px #999;
background-color:white;
position:absolute;
margin-top:-1.7em;
margin-left:2em;
padding:1em;
}
#tocinfobox table tr td:nth-child(2){
text-align:left;
}
#tocinfobox table tr th:nth-child(2){
text-align:left;
}
#tocinfobox table tr th{
vertical-align:bottom;
}
#itemdialog .selectheadimage .imageAddPreview img {
width: 100%;
height: auto;
}
#itemdialog .selectheadimage .imageAddList ul#addimagelist {
background-color: white;
height: 8em;
list-style: none;
padding: 0.2em 0;
overflow-y: scroll;
border: 1px solid #777;
}
#itemdialog .selectheadimage .imageAddList ul#addimagelist li {
padding: 0.1em 0.4em;
cursor: pointer;
}
#itemdialog .selectheadimage .imageAddList ul#addimagelist li:nth-child(even) {
background-color: #f9f9f9;
}
#itemdialog .selectheadimage .imageAddList ul#addimagelist li.previewed {
background-color: #ffa;
}
#itemdialog .selectheadimage .imageAddList ul#addimagelist li:hover {
box-shadow: inset 0 0 2px red;
}
#itemdialog input[name="currentTitle"] {
display: block;
width: 100%;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
#itemdialog .imageAddPreview h3 {
margin: 3em 8em 0 8em;
padding: 0.5em 0;
text-align: center;
background-color: white;
}
/**********************************************************
* Check translation!
**********************************************************/
body[booktype="authorbook"] .CheckTranslation {
border: 2px dashed red;
border-radius: 5px;
}
body[booktype="authorbook"] .CheckTranslation:before {
content: "Check translation. The original element has changed.";
border: 1px solid red;
border-bottom: none;
border-radius: 5px;
display: block;
color: white;
background-color: red;
margin: 0;
padding: 0.5em 1em;
}
body[booktype="authorbook"][lang="fi"] .CheckTranslation:before {
content: "Tarkista käännös. Alkuperäinen on muuttunut.";
}
body[booktype="authorbook"] #pageOne .ui-accordion h3 .translationmark
{
display: inline-block;
padding: 0.2em 0.3em 0.2em 0.2em;
margin-left: 1em;
border:1px solid #f00;
background-color:#a00;
border-radius:8px;
color:white;
}
/****************************************************
* Action buttons -bar
****************************************************/
.actionbuttonset {
display: inline-block;
}
#actionButtons {
position: fixed;
bottom: 0;
/* height: 35px;*/
left: 150px;
right: 150px;
padding: 3px 2em;
background-color: #ffa;
border: 1px solid #888;
border-radius: 8px 8px 0 0;
box-shadow: 2px 2px 4px #888;
}
#actionButtons .actionmenu {display: inline-block;}
#actionButtons .actionmenu .actionmenucontainer {display: none;}
#actionButtons .actionmenu.menuopen .actionmenucontainer {display: block;}
#actionButtons .actionmenu {position: relative;}
#actionButtons .actionmenu .actionmenucontainer {position: absolute; top:0;}
#actionButtons .actionmenu .actionmenucontainer ul.actionmenuitemlist {position: absolute; bottom:0; border: none; background-color: transparent; padding: 0;margin:0;}
#actionButtons .actionmenu .actionmenucontainer ul.actionmenuitemlist {list-style: none;}
#actionButtons .actionmenu .actionmenucontainer ul.actionmenuitemlist button {display: block;width: 10em;}
#actionButtons .pagecommbutton,
#actionButtons .updatebuttons,
#actionButtons .editbuttonset
{display: inline-block;}
#actionButtons.context_subsection.context_assignments li.context_subsection
{display: block;}
#actionButtons.context_frontPage li.context_frontPage,
#actionButtons.context_chapter li.context_chapter,
#actionButtons.context_section li.context_section,
#actionButtons.context_subsection li.context_subsection,
#actionButtons.context_subsection.context_assignments li.context_assignments
{display: none;}
ul.actionmenuitemlist li.level2 {display: none;}
ul.actionmenuitemlist.level1 li.level2 {display: none;}
ul.actionmenuitemlist.level2 li.level1 {display: none;}
ul.actionmenuitemlist.level2 li.level2 {display: block;}
/****************************************************
* Authortools
****************************************************/
.ui-dialog {box-shadow: 10px 10px 30px rgba(0,0,0,0.4);}
.dialogelement textarea {
min-height: 20em;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.dialogelement textarea.pre_elem_textarea,
.dialogelement textarea.post_elem_textarea {
min-height: 8em;
}
.dialogelement.add_assignment_elem .mathquill-textbox,
.dialogelement.add_example_head .mathquill-textbox,
.dialogelement.add_theory_head .mathquill-textbox {
width: 100%;
background-color: white;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.dialogelement.add_assignment_elem .mathdisplaystyle .mathquill-editable,
.dialogelement.add_example_elem .add_example_formula.mathquill-editable,
.dialogelement.add_theory_elem .add_theory_formula.mathquill-editable {
min-width: 5em;
background-color: white;
}
.dialogelement .mathdisplaystyle {
margin: 0.5em 0;
}
.dialogelement.assignment_block .qededitor .command_qededit {
display: none;
}
.dialogelement.ebooktitle input.ebooktitleInput {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.dialogelement.imageCaption .mathquill-textbox {width: 100%;}
.dialogelement.tag_insert {margin-top: 2em;}
.dialogelement.imageSelect {position: relative;}
.dialogelement.imageSelect .imageAddList {width: 35%; float: left; background-color: white; max-height: 400px; overflow-x: auto; border-top: 1px solid black; border-left: 1px solid black; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa;}
.dialogelement.imageSelect .imageAddPreview {width: 60%; background: white; min-height: 200px; float: left; margin-left: 1em; border-top: 1px solid black; border-left: 1px solid black; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa;}
.dialogelement.imageSelect:after {display: block; clear: both; content: " ";}
.dialogelement.imageSelect .imageAddPreview img {max-width: 99%; height: auto;}
.dialogelement.imageSelect .imageAddList ul {list-style: none; padding-left: 0.5em;}
.dialogelement.imageSelect .imageAddList ul li {cursor: pointer; margin-left: 0; margin-right: 0.5em; padding-left: 0.1em;}
.dialogelement.imageSelect .imageAddList ul li:hover {text-decoration: underline;}
.dialogelement.imageSelect .imageAddList ul li.previewed {background-color: #eaeaea;}
.dialogelement.imageSelect .imageAddControl {margin-bottom: 1em;}
table.graph_add_table td {background-color: white; color: black; text-align: left; padding: 0.2em 0.5em; border: 1px solid #aaa;}
table.graph_add_table th {background-color: black; color: white; text-align: left; padding: 0.2em 0.5em; border: 1px solid #aaa;}
table.graph_add_table {width: 100%; border-collapse: collapse;}
table.graph_add_table td .mathquill-editable {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
table.graph_add_table td input[type="text"] {
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.dialogelement .editvalues {display: none;}
.dialogelement.add_table_edittypes.edittypes .edittypes,
.add_table_edittypes.edittypes .edittypes
{display: none;}
.dialogelement.add_table_edittypes.edittypes .editvalues,
.add_table_edittypes.edittypes .editvalues
{display: inline;}
.dialogelement.original_content .original_text,
.dialogelement.default_content .original_text {
display: block;
background-color: white;
border: 1px solid #555;
white-space: pre-wrap;
}
.dialogelement.original_content .original_text.hidden_original,
.dialogelement.default_content .original_text.hidden_default {
display: none;
}
#authordialog_addteacherelement .add_elements_head span.mathquill-textbox,
#authordialog_addteacherelement span.add_content_text.mathquill-textbox,
#authordialog_addgraphbox .add_graph_caption .mathquill-textbox
{display: block;}
#authordialog_addteacherelement .solutionAnswer .mathquill-textbox {
display: block;
background-color: white;
}
#authordialog_addteacherelement .mathdisplaystyle {text-align: center;}
#authordialog_addteacherelement .mathdisplaystyle .add_content_formula {background-color: white;}
#authordialog_addteacherelement .add_buttonset,
.dialogelement .add_buttonset {margin: 1em 0;}
.dialogelement.isPrivat .isPrivatselect .publishthis {text-decoration: underline; color: #55f;}
.dialogelement.isPrivat .isPrivatselect .publishthis:hover {cursor: pointer;}
.dialogelement.isPrivat .isPrivatselect .publishthis span {display: none;}
.dialogelement.isPrivat .isPrivatselect .publishthis.dontpublish span {display: inline; color: red;}
/******************************************
* Authortools - add element / remove element / edit element / copy element
******************************************/
.bookpage > [tiddler].copyelems > [tiddler],
.bookpage > [tiddler].addelems > [tiddler],
.bookpage > [tiddler].removeelems > [tiddler],
.bookpage > [tiddler].editelems > [tiddler] {
border: 1px dashed #888;
border-radius: 8px;
position: relative;
display: block;
padding: 0.5em;
margin: 1em 2em;
}
.bookpage > [tiddler].copyelems > [tiddler]:hover,
.bookpage > [tiddler].addelems > [tiddler]:hover,
.bookpage > [tiddler].removeelems > [tiddler]:hover,
.bookpage > [tiddler].editelems > [tiddler]:hover {
border: 1px solid black;
}
.bookpage > [tiddler].copyelems > [tiddler]:after,
.bookpage > [tiddler].addelems > [tiddler]:after,
.bookpage > [tiddler].removeelems > [tiddler]:after,
.bookpage > [tiddler].editelems > [tiddler]:after {
content: " ";
display: block;
clear: both;
}
.bookpage > [tiddler].addelems > [tiddler] .addelembefore,
.bookpage > [tiddler].addelems > [tiddler] .addelemafter {
position: absolute;
right: 0;
margin-right: -0.5em;
padding-left: 0.3em;
padding-right: 0.3em;
border: 1px solid #0a0;
border-radius: 8px;
background-color: #0a0;
color: white;
font-weight: bold;
}
.bookpage > [tiddler] > [tiddler] .solvethis,
.bookpage > [tiddler].removeelems > [tiddler] .removethis {
position: absolute;
right: 0;
top: 0;
margin-right: -0.5em;
margin-top: -0.5em;
padding-left: 0.3em;
padding-right: 0.3em;
border: 1px solid #a00;
border-radius: 8px;
background-color: #aaa;
color: white;
font-weight: bold;
}
.bookpage > [tiddler] > [tiddler] .solvethis {
border: 1px solid #00a;
background-color: #00a;
}
.bookpage > [tiddler].removeelems > [tiddler] .removethis.selectedRemove {
background-color: #a00;
}
.bookpage > [tiddler].editelems > [tiddler] .editthis,
.bookpage > [tiddler].editelems > [tiddler] .translatethis {
position: absolute;
right: 0;
top: 0;
margin-right: -0.5em;
margin-top: -0.5em;
padding-left: 0.3em;
padding-right: 0.3em;
border: 1px solid #00a;
border-radius: 8px;
background-color: #00a;
color: white;
font-weight: bold;
}
.bookpage > [tiddler].copyelems > [tiddler] .copythis {
position: absolute;
right: 0;
top: 0;
margin-right: -0.5em;
margin-top: -0.5em;
padding-left: 0.3em;
padding-right: 0.3em;
border: 1px solid #0a0;
border-radius: 8px;
background-color: #0a0;
color: white;
font-weight: bold;
}
.bookpage > [tiddler].addelems > [tiddler] .addelembefore{
top: 0;
margin-top: -0.5em;
}
.bookpage > [tiddler].addelems > [tiddler] .addelemafter {
botton: 0;
margin-bottom: -0.5em;
}
.bookpage > [tiddler].addelems > [tiddler] .addelembefore:hover,
.bookpage > [tiddler].addelems > [tiddler] .addelemafter:hover {
background-color: #0d0;
}
.bookpage > [tiddler].removeelems > [tiddler] .removethis:hover {
background-color: #ddd;
}
.bookpage > [tiddler].removeelems > [tiddler] .removethis.selectedRemove:hover {
background-color: #d00;
}
.bookpage > [tiddler] > [tiddler] .solvethis:hover {
background-color: #00d;
}
.bookpage > [tiddler].editelems > [tiddler] .editthis:hover,
.bookpage > [tiddler].editelems > [tiddler] .translatethis:hover {
background-color: #00d;
}
.bookpage > [tiddler].copyelems > [tiddler] .copythis:hover {
background-color: #0d0;
}
.bookpage > [tiddler] > [tiddler] .solvethis a,
.bookpage > [tiddler].addelems > [tiddler] .addelembefore a,
.bookpage > [tiddler].addelems > [tiddler] .addelemafter a,
.bookpage > [tiddler].copyelems > [tiddler] .copythis a,
.bookpage > [tiddler].removeelems > [tiddler] .removethis a,
.bookpage > [tiddler].editelems > [tiddler] .editthis a,
.bookpage > [tiddler].editelems > [tiddler] .translatethis a{
color: white;
background-color:transparent;
}
.bookpage > [tiddler] > [tiddler] .solvethis a:hover,
.bookpage > [tiddler].addelems > [tiddler] .addelembefore a:hover,
.bookpage > [tiddler].addelems > [tiddler] .addelemafter a:hover,
.bookpage > [tiddler].removeelems > [tiddler] .removethis a:hover,
.bookpage > [tiddler].editelems > [tiddler] .editthis a:hover,
.bookpage > [tiddler].editelems > [tiddler] .translatethis a:hover{
color: white;
background-color:transparent;
}
.bookpage [tiddler].copyelems .sdbookassignmentlist div.ui-accordion-content,
.bookpage [tiddler].removeelems .sdbookassignmentlist div.ui-accordion-content,
.bookpage [tiddler].editelems .sdbookassignmentlist div.ui-accordion-content,
.bookpage [tiddler] .sdbookassignmentlist div.ui-accordion-content.dontcloseme {
display: block!important;
}
.bookpage .teacherAccordions .assignmentAccordion0 h3 .solvethis,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .solvethis,
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis {
position: absolute;
right: 0;
top: 0;
margin-right: 0.2em;
margin-top: 0.2em;
border: 1px solid #a00;
border-radius: 8px;
background-color: #aaa;
color: white;
font-size: 70%;
font-weight: bold;
}
.bookpage .teacherAccordions .assignmentAccordion0 h3 .solvethis,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .solvethis {
border: 1px solid #00a;
background-color: #00a;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis.selectedRemove,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis.selectedRemove {
background-color: #a00;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis:hover {
background-color: #ddd;
}
.bookpage .teacherAccordions .assignmentAccordion0 h3 .solvethis:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .solvethis:hover {
background-color: #00d;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis.selectedRemove:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis.selectedRemove:hover {
background-color: #d00;
}
.bookpage .teacherAccordions .assignmentAccordion0 h3 .solvethis a,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .solvethis a,
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis a,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis a{
color: white;
background-color:transparent;
padding: 0.3em 0.6em;
}
.bookpage .teacherAccordions .assignmentAccordion0 h3 .solvethis a:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .solvethis a:hover,
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .removethis a:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .removethis a:hover{
color: white;
background-color:transparent;
}
.bookpage > [tiddler].editelems .sdbookassignmentlist .ui-accordion h3 .editthis,
.bookpage > [tiddler].editelems .sdbookassignmentlist .ui-accordion h3 .translatethis {
position: absolute;
right: 0;
top: 0;
margin-right: 0.2em;
margin-top: 0.2em;
padding-left: 0;
padding-right: 0;
border: 1px solid #00a;
border-radius: 8px;
background-color: #00a;
color: white;
font-weight: bold;
font-size: 70%;
}
.bookpage > [tiddler].editelems .sdbookassignmentlist .ui-accordion h3 .editthis a,
.bookpage > [tiddler].editelems .sdbookassignmentlist .ui-accordion h3 .translatethis a {
color: white;
background: transparent;
padding: 0.3em 0.6em;
}
.bookpage .question_text .editthis,
.bookpage .question_text .translatethis {
display: inline-block;
margin-left: 2em;
padding-left: 0;
padding-right: 0;
border: 1px solid #00a;
border-radius: 8px;
background-color: #00a;
color: white;
font-weight: bold;
font-size: 70%;
}
.bookpage .question_text .editthis a,
.bookpage .question_text .translatethis a {
color: white;
background: transparent;
padding: 0.3em 0.6em;
}
.bookpage .grapheditor {
position: relative;
margin: 1em 0.5em;
}
.notTranslated .editthis,
.notTranslated .notTranslatedimage .translatethis,
h3.notTranslated + div li div.notTranslated .translatethis {
display: none;
}
.translatealert {
font-size: 140%;
color: red;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .copythis,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .copythis {
position: absolute;
right: 0;
top: 0;
margin-right: 0.2em;
margin-top: 0.2em;
border: 1px solid #0a0;
border-radius: 8px;
background-color: #aaa;
color: white;
font-size: 70%;
font-weight: bold;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3.selectedforcopy .copythis,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3.selectedforcopy .copythis {
background-color: #0a0;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .copythis:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .copythis:hover {
background-color: #ddd;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3.selectedforcopy .copythis:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3.selectedforcopy .copythis:hover {
background-color: #0d0;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .copythis a,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .copythis a{
color: white;
background-color:transparent;
padding: 0.3em 0.6em;
}
.bookpage .sdbookassignmentlist .otherassignmentAccordion h3 .copyhis a:hover,
.bookpage .sdbookassignmentlist .assignmentAccordion0 h3 .copythis a:hover{
color: white;
background-color:transparent;
}
/************************************************************************************
* Otherassignment authortool dialog
************************************************************************************/
.dialogelement .mathquill-textbox {background-color: white;}
.add_otherassignment_head .mathquill-textbox {width: 95%;}
li.question .questionPlain, li.question .questionMulti, li.question .questionShortA {display: block;}
.otherassignment_list ol > li.question {padding-bottom: 0.5em; border-bottom: 2px solid #999; margin-top: 1em; margin-bottom: 1em;}
ul.multichoise {list-style: none;}
ul.multichoise li.correct:before {content: "\2714"; font-size: 180%; color: green;}
ul.multichoise li.incorrect:before {content: "\2717"; font-size: 180%; color: red;}
.otherassignment_list span.solution,
.sdbooksolshortanswer .solution
{background-color: #afa; border: 1px solid #9f9; min-width: 2em; display: inline-block;}
.otherassignment_list button.addMultiwrong {padding: 0; margin: 0; font-size: 80%; margin-left: 3.5em;}
.otherassignment_list .addSubQ, .dialogelement.add_otherassignment_elem {border: 1px solid #999; padding: 0.5em; display: inline; border-radius: 5px; background-color: #fafafa; box-shadow: 2px 2px 3px #999; margin: 0.2em 0 1em 2em; display: inline-block;}
textarea.otherassignment_elem.add_otherassignment_text {min-height: 1em; height: 3em;}
.otherassignment_list hr {margin-left: 3em;}
/************************************************************************************
* Extrabox editing/translating/adding
************************************************************************************/
div.addsubelement {
border: 1px solid black;
border-radius: 4px;
padding: 0.3em;
position: absolute;
right: 6em;
background: blue;
color: white;
margin-top: -5em;
margin-bottom: 0;
box-shadow: 4px 4px 4px rgba(0,0,0,0.5);
}
div.addsubelement a {
font-weight: bold;
color: white;
text-decoration: none;
}
/*************************
Coursecommentapp styles
**************************/
#coursecommentnavi {
margin-top: -2em;
}
#coursecommentnavi ul#commentList {
background-color: #f0f0f0;
height: 15em;
position: relative;
border: 1px solid black;
border-top: 2px solid #777;
border-left: 2px solid #777;
border-right: 2px solid #aaa;
border-bottom: 2px solid #aaa;
overflow: auto;
padding: 0;
}
#coursecommentnavi ul#commentList li.selectComment {
padding: 0.2em 0.5em;
cursor: pointer;
border-left:15px solid #ffa;
border-right:15px solid #ffa;
border-top:1px solid gray;
}
#coursecommentnavi ul#commentList li.selectComment.content {
border-left:15px solid #afa;
border-right:15px solid #afa;
}
#coursecommentnavi ul#commentList li.selectComment.system {
border-left:15px solid #aff;
border-right:15px solid #aff;
}
#coursecommentnavi ul#commentList li.selectComment.layout {
border-left:15px solid #faf;
border-right:15px solid #faf;
}
#coursecommentnavi ul#commentList li.selectComment.shownComment {
border: 1px solid #a00;
box-shadow: inset 0 5px 8px rgba(150,0,0,0.5), inset 0 -5px 8px rgba(150,0,0,0.5);
background-color: #fee;
}
#coursecommentnavi ul#commentList li.selectComment:nth-child(odd) {
background-color: #fff6d5;
}
#coursecommentnavi ul#commentList li.selectComment:nth-child(even) {
background-color: #fea;
}
#coursecommentnavi ul#commentList li.selectComment .commentSent {
display: inline;
font-size: 70%;
}
#coursecommentnavi ul#commentList li.selectComment .commentSender {
font-weight: bold;
font-style: italic;
display: block;
}
#coursecommentnavi ul#commentList li.selectComment .commentToText {
display: block;
font-weight: bold;
}
#coursecommentnavi ul#commentList li.selectComment span.pagecommenttype{
font-style: italic;
display: block;
float: right;
padding: 0.1em;
text-shadow: 1px 1px 0.5px white;
}
.pagecommentblock .pagecommenthead button.showcommentbody{
margin-top: -1em;
margin-bottom: 0.3em;
margin-right: 0.5em;
}
#coursecommentnavi ul#commentList li.selectComment button{
margin-top: 3px;
}
.pagecommentblock .pagecommenthead button.showcommentbody,
.pagecommentblock .pagecommentbody button.hideComment,
#coursecommentnavi ul#commentList li.selectComment button{
float:right;
padding:0 1px;
border:1px solid gray;
border-radius:3px;
background: -webkit-linear-gradient(top, #8A5C00 , #C2A366);
background: -moz-linear-gradient(top, #8A5C00 , #C2A366);
background: -o-linear-gradient(top, #8A5C00 , #C2A366);
background: -ms-linear-gradient(top, #8A5C00 , #C2A366);
background: linear-gradient(top, #8A5C00 , #C2A366);
cursor:pointer;
box-shadow:3px 3px 4px #888888;
color:white;
text-shadow:0 0 5px gray;
}
#updatecoursecomments{
float:left;
margin-left:1em;
}
#showHidden{
float:right;
margin-right:1em;
}
#showHidden,
#updatecoursecomments{
font-size:75%;
padding:0 1px;
border:1px solid gray;
border-radius:3px;
background: -webkit-linear-gradient(top, #8A5C00 , #C2A366);
background: -moz-linear-gradient(top, #8A5C00 , #C2A366);
background: -o-linear-gradient(top, #8A5C00 , #C2A366);
background: -ms-linear-gradient(top, #8A5C00 , #C2A366);
background: linear-gradient(top, #8A5C00 , #C2A366);
cursor:pointer;
box-shadow:3px 3px 4px #888888;
color:white;
text-shadow:0 0 5px gray;
}
#coursecommentnavi ul#commentList li.selectComment.thispageComment {
background: rgb(240,249,255); /* Old browsers */
background: -moz-linear-gradient(top, rgba(240,249,255,1) 0%, rgba(203,235,255,1) 47%, rgba(161,219,255,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(240,249,255,1)), color-stop(47%,rgba(203,235,255,1)), color-stop(100%,rgba(161,219,255,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f0f9ff', endColorstr='#a1dbff',GradientType=0 ); /* IE6-9 */
}
#contentWrapper[pageopen="coursecomment"] #pageTwoWrapper {overflow-y: scroll;}
/*}}}*/
/***
|''Name:''|StyleSheetEbookDefaultTheme|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Default theme styling for E-math ebook|
|''Version:''|1.3|
|''Date:''|November 2, 2012|
|''Contact:''|pesasa@iki.fi|
!!!!!Revisions
<<<
20131210.1406 ''add''
* Scaling for ebookimages
20131119.1156 ''add''
* fullscreenmode for "bigbox"-mode elements
20131003.1530 ''add''
* closepagetwobutton
20130926.1153 ''add''
* Less margin for ebookboxes in teacherEditmode
20130917.1520 ''add''
* Added the support for Eulexia font.
<<<
!!!!!Code
***/
/*{{{*/
@font-face {
font-family: 'eulexia';
src: url([[eulexia.ttf]]) format('truetype');
font-weight: normal;
font-style: normal;
}
/**Remove me!
.teacherbox .teachertoolbar button.teacherEdit:before {content: url([[icon-edit.png]]); margin: 2px 5px 2px 0; vertical-align: middle; display: inline-block;}
.teacherbox .teachertoolbar button.teacherDelete:before {content: url([[icon-trash-red.png]]); margin: 2px 5px 2px 0; vertical-align: middle; display: inline-block;}
.teacherbox .teachertoolbar button.teacherEdit span {display: none;}
.teacherbox .teachertoolbar button.teacherDelete span {display: none;}
*/
/********************************************************************
* Default theme for Emathbook
********************************************************************/
/*****************
* Body
*****************/
body {background-color: #cdde87;}
/*****************
* Book pages
*****************/
.bookpage h1 {
color: #3F4426;
font-family: serif;
border-bottom: 2px solid #3F4426;
}
.bookpage h2 {
color: #3F4426;
font-family: serif;
}
/**********************************************************
* Linebreaks
**********************************************************/
.bookpage span.eblinebreak {
display: block;
height: 0;
margin: 0;
margin-top: 1.5em;
}
.bookpage span.ebparbreak {
display: block;
height: 0;
margin-top: 1.5em;
}
/**********************************************************
* Math
**********************************************************/
.mathdisplaystyle {
text-align: left;
margin-left: 3em;
}
.mathdisplaystyle + br + .mathdisplaystyle {
margin-top: 0;
}
/**********************************************************
* Lists
**********************************************************/
.algorithmlist ol li:nth-child(2n+1) {
background-color: #ffa;
}
.algorithmlist ol li:nth-child(2n) {
background-color: #ffd;
}
/**********************************************************
* Fullscreenmode for Modelsolution, Hint and Extra elements
* in "bigbox"-mode
**********************************************************/
.extraboxcontent .extra_presentationmode_button {
display: inline-block;
margin: .5em 1em;
border: 1px solid #999;
border-radius: 0.3em;
font-weight: bold;
font-size: 90%;
color: blue;
cursor: pointer;
text-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5);
box-shadow: -1px -1px 1px rgba(0,0,0,0.2), inset 1px 1px 1px rgba(255,255,255,0.5), inset -1px -1px 1px rgba(0,0,0,0.3), 1px 1px 1px rgba(255,255,255,0.5);
background: rgb(238,238,238); /* Old browsers */
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
.extraboxcontent .extra_presentationmode_button:active {
box-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5);
}
.extraboxcontent .extra_presentationmode_button:hover ul {
background: rgba(255,255,255,0.5);
}
.extraboxcontent .extra_presentationmode_button ul {
list-style: none;
margin: 0;
padding: 0.1em 0.3em;
border-radius: 0.3em;
}
.extraboxcontent .extra_presentationmode_button ul li {
margin: 0;
padding: 0;
}
.extraboxcontent.extrabox_fullscreen .extra_presentationmode_button{
position:fixed;
bottom:0;
left:0;
}
.hasbigbox .extraboxwrapper.bigbox div.extraboxcontent.extrabox_fullscreen {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: 0;
background: white;
z-index: 1002;
font-size: 150%;
overflow-y: scroll;
padding:0 3em;
}
.extraboxwrapper.fullscreenmode{
z-index:205;
}
.hasbigbox .extraboxwrapper.bigbox div.extraboxcontent.extrabox_fullscreen h1 {
border-radius:0;
margin:0 -2.5em;
}
.extraboxcontent ul.inarrows,
.extraboxcontent.extrabox_fullscreen ul.outarrows{
display:none;
}
.extraboxcontent ul.outarrows,
.extraboxcontent.extrabox_fullscreen ul.inarrows{
display:block;
}
/**********************************************************
* Extraclasses for Hint and Extra elements
**********************************************************/
.ebookbox[hintclasses~="highlighttasks"] .qededitor .sdtable td.task,
.ebookbox[extraclasses~="highlighttasks"] .qededitor .sdtable td.task {
color: #a0a; /* violet */
text-shadow: 0 0 1px #f0f;
}
.ebookbox[hintclasses~="highlightassumptions"] .qededitor .sdtable td.assumption,
.ebookbox[extraclasses~="highlightassumptions"] .qededitor .sdtable td.assumption {
color: green;
text-shadow: 0 0 1px green;
}
.ebookbox[hintclasses~="highlightobservations"] .qededitor .sdtable td.obsmotivation,
.ebookbox[extraclasses~="highlightobservations"] .qededitor .sdtable td.obsmotivation,
.ebookbox[hintclasses~="highlightobservations"] .qededitor .sdtable td.observation,
.ebookbox[extraclasses~="highlightobservations"] .qededitor .sdtable td.observation {
color: #ff8000; /* orange */
text-shadow: 0 0 1px #ff8000;
}
.ebookbox[hintclasses~="highlightrelations"] .qededitor .sdtable td.relation,
.ebookbox[extraclasses~="highlightrelations"] .qededitor .sdtable td.relation {
color: red;
text-shadow: 0 0 1px red;
}
.ebookbox[hintclasses~="highlightmotivations"] .qededitor .sdtable td.motivation,
.ebookbox[extraclasses~="highlightmotivations"] .qededitor .sdtable td.motivation {
color: blue;
text-shadow: 0 0 1px blue;
}
.ebookbox[hintclasses~="highlightterms"] .qededitor .sdtable td.term,
.ebookbox[extraclasses~="highlightterms"] .qededitor .sdtable td.term {
color: black;
text-shadow: 0 0 1px black;
}
.ebookbox[hintclasses~="highlightsubderivations"] .qededitor .sdtable td.subderivation,
.ebookbox[extraclasses~="highlightsubderivations"] .qededitor .sdtable td.subderivation {
background-color: #fcc;
box-shadow: 1px 1px 3px red;
}
/**********************************************************
* Ebookimages
**********************************************************/
.ebookbox .ebookimage img {
max-width: 100%;
height: auto;
}
/**********************************************************
* Geocaptions
**********************************************************/
ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #ffe;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
span.geocaption {
background-color: #ffa;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
/**********************************************************
* Solutions
**********************************************************/
.solutionAccordion .ui-accordion-content {
background: #f5f5f5 none;
}
/**********************************************************
* Buttons
**********************************************************/
button.ebook-button,
a.ebook-button {
cursor: pointer;
height: auto;
width: auto;
min-height: 20px;
min-width: 20px;
display: inline-block;
margin: 1px 2px;
padding: 2px;
border: none;
border-radius: 4px;
vertical-align: middle;
text-align: center;
font-weight: bold;
font-size: 100%;
box-shadow: -1px -1px 1px rgba(0,0,0,0.4), inset 1px 1px 1px rgba(255,255,255,0.4), inset -1px -1px 1px rgba(0,0,0,0.4), 1px 1px 1px rgba(255,255,255,0.4);
background: rgb(254,252,234); /* Old browsers */
background: -moz-linear-gradient(top, rgba(254,252,234,1) 0%, rgba(241,218,54,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,1)), color-stop(100%,rgba(241,218,54,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefcea', endColorstr='#f1da36',GradientType=0 ); /* IE6-9 */
}
button.ebook-button:hover,
a.ebook-button:hover {
background: rgba(254,252,234,08); /* Old browsers */
background: -moz-linear-gradient(top, rgba(254,252,234,0.5) 0%, rgba(241,218,54,0.5) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,0.5)), color-stop(100%,rgba(241,218,54,0.5))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(254,252,234,0.5) 0%,rgba(241,218,54,0.5) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(254,252,234,0.5) 0%,rgba(241,218,54,0.5) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(254,252,234,0.5) 0%,rgba(241,218,54,0.5) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(254,252,234,0.5) 0%,rgba(241,218,54,0.5) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefcea', endColorstr='#f1da36',GradientType=0 ); /* IE6-9 */
}
button.ebook-button.buttonMedium svg,
a.ebook-button.buttonMedium svg {
width: 30px;
height: 30px;
}
button.ebook-button.buttonLarge svg,
a.ebook-button.buttonLarge svg {
width: 40px;
height: 40px;
}
button.ebook-button.buttonHuge svg,
a.ebook-button.buttonHuge svg {
width: 50px;
height: 50px;
}
/**********************************************
* Home assignments listing
**********************************************/
.pageAssignemtns {
list-style-type: none;
padding: 1em;
margin: 0px;
}
.checkassLi b{
display:block;
}
.checkassLi {
padding: 1.3em 0;
border-bottom:2px dotted #aaa;
}
.assignmentText{
display:block;
padding-left:1em;
padding-bottom:0.4em;
border-left:2px ridge black;
border-bottom:2px ridge black;
margin:0.3em 1em 0.5em 1em;
}
/**********************************************
* Languages
**********************************************/
.contentlang { display: none; }
[lang="fi"] div.contentlang_fi,
[lang="en"] div.contentlang_en,
[lang="sv"] div.contentlang_sv,
[lang="et"] div.contentlang_et {
display: block;
}
/*
[lang="fi"] span.contentlang_fi,
[lang="en"] span.contentlang_en,
[lang="sv"] span.contentlang_sv,
[lang="et"] span.contentlang_et {
display: inline;
}
*/
span.contentlang_fi:lang(fi),
span.contentlang_en:lang(en),
span.contentlang_sv:lang(sv),
span.contentlang_et:lang(et) {
display: inline;
}
/**********************************************
* Publish-icon
**********************************************/
.teacherbox {margin-top: 1em;}
.teacherbox .ebookbox {margin: 0 0.3em 0.5em 0;}
.teacherbox.notpublishedelement {border-radius: 0.3em; background-color: #fee; padding: 0.3em; border: 1px solid #fdd; box-shadow: 0 0 4px rgba(255,150,150,0.5);}
/*.teacherbox.notpublishedelement button.publishbutton {border-radius: 0.5em; border: 1px solid #999; padding-left: 30px; margin-bottom: 0.2em; cursor: pointer;}*/
/*.teacherbox.notpublishedelement button.publishbutton:hover {box-shadow: 0 0 5px rgba(0,0,0,0.3); background-color: #eaeaea;}*/
/*.teacherbox.notpublishedelement button.publishbutton:before {content: url([[icon-publish.png]]); margin: 2px 5px 2px -25px; vertical-align: middle; display: inline-block;}*/
.teacherbox.notpublishedelement button.publishbutton span {display: none;}
.teacherbox.notpublishedelement button.publishbutton:lang(fi):after {content: "Julkaise";}
.teacherbox.notpublishedelement button.publishbutton:lang(en):after {content: "Publish";}
.teacherbox.notpublishedelement button.publishbutton:lang(sv):after {content: "Publicera";}
.teacherbox.notpublishedelement button.publishbutton:lang(et):after {content: "Avalda";}
.teacherAccordions h3 button.publishbutton {display: inline-block; border: none; border-radius: 0.5em; padding: 0px; cursor: pointer; position: absolute; top: 0; right: 80px; background-color: transparent; width: 30px; height: 30px;}
.teacherAccordions h3 button.publishbutton:before {display: inline-block; content: url([[icon-publish.png]]); margin: 0; vertical-align: middle; width: 30px; height: 30px;}
.teacherAccordions h3 button.publishbutton:hover:before {box-shadow: 0 0 5px rgba(0,0,0,0.3); border-radius: 3px;}
.teacherAccordions h3 button.publishbutton span {display: none;}
.extraboxcontent button.publishbutton {border-radius: 0.5em; border: 1px solid #999; padding-left: 30px; margin: 0.2em 0.2em 0.2em 0.5em; cursor: pointer;}
.extraboxcontent button.publishbutton:hover {box-shadow: 0 0 5px rgba(0,0,0,0.3); background-color: #eaeaea;}
.extraboxcontent button.publishbutton:before {content: url([[icon-publish.png]]); margin: 2px 5px 2px -25px; vertical-align: middle; display: inline-block;}
.extraboxcontent button.publishbutton span {display: none;}
.extraboxcontent button.publishbutton:lang(fi):after {content: "Julkaise";}
.extraboxcontent button.publishbutton:lang(en):after {content: "Publish";}
.extraboxcontent button.publishbutton:lang(sv):after {content: "Publicera";}
.extraboxcontent button.publishbutton:lang(et):after {content: "Avalda";}
/**********************************************
* Teacherbox
**********************************************/
.assignment_text.teacherEditmode,
.teacherbox.teacherEditmode {
border-radius: 0.3em;
background-color: #eef;
padding: 0.3em;
padding-top: 1em;
border: 1px solid #ddf;
box-shadow: 0 0 4px rgba(150,150,255,0.5);
}
div.teacherbox.teacherEditmode .ebookbox > div {
margin: 0 0.1em;
}
.teacherbox.teacherEditmode > .teachertoolbar {
display: none;
}
.teacherbox.teacherEditmode .teacherset .teachertoolbar {
text-align: right;
}
#ask_type {
margin: 0.5em 1.5em;
background-color: #eef;
border: 1px solid #ddf;
box-shadow: 0 0 4px rgba(150,150,255,0.5);
padding: 0.5em 0.8em;
}
#ask_type button.typeButtons {
margin-right: 0.8em;
}
#pageOne.teacherpageEdit > [tiddler] {
margin-bottom: 8em;
}
/**********************************************
* Appblock
**********************************************/
.appblock {
border: 1px solid #aaa;
border-radius: 0.5em;
box-shadow: 0 0 3px rgba(0,0,0,0.3);
padding: 0.5em;
background-color: #ffd;
}
.appblock h2 {
margin: 0 0.2em 0.3em 0.2em;
text-shadow: 2px 2px 3px rgba(0,0,0,0.3);
border-bottom: 1px solid black;
}
/**********************************************
* Pagecomment
**********************************************/
#authordialog_pagecomment {
background-image: url([[envelope.png]]);
background-position: right 10px;
background-repeat: no-repeat;
}
/**********************************************
* indicatorlights
**********************************************/
#bottomrightmenu ul.booksettingsselection {padding-top: 0; border-top-width: 3px;}
#bottomrightmenu ul.booksettingsselection #indicatorlights {margin:0; padding: 3px 5px; border: none; border-radius: 0; background-color: orange;}
#indicatorlights ul {position: static; border: none; border-radius: 0; box-shadow: none; margin: 0; padding: 0; background-color: transparent;}
#indicatorlights ul li.indicator {display: inline-block; background-color: transparent; padding: 25px 0.2em 0.2em 0.2em; min-width: 25px; border: none; min-width: 3em;}
#indicatorlights ul li#onlineindicator {background: transparent url([[icon-online-check.png]]) 3px 3px no-repeat;}
#indicatorlights ul li#onlineindicator:after {content: "connecting"; text-decoration: blink;}
#indicatorlights ul li#onlineindicator.serveronline {background: transparent url([[icon-online.png]]) 3px 3px no-repeat;}
#indicatorlights ul li#onlineindicator.serveronline:after {content: "online"; text-decoration: none;}
#indicatorlights ul li#onlineindicator.serveroffline {background: transparent url([[icon-offline.png]]) 3px 3px no-repeat;}
#indicatorlights ul li#onlineindicator.serveroffline:after {content: "offline"; color: red;}
#indicatorlights ul li#onlineindicator:after {text-shadow: 0 0 4px white;}
/**********************************************
* icons
**********************************************/
.ui-icon.emui-icon-print {background-image: url([[icon-print.png]]); min-height: 30px; min-width: 30px; margin-top: -15px; margin-left: -15px;}
.ui-icon.emui-icon-preview {background-image: url([[icon-preview.png]]); min-height: 30px; min-width: 30px; margin-top: -15px; margin-left: -15px;}
.ui-icon.emui-icon-comment-show {background-image: url([[icon-comment-show.png]]); min-height: 30px; min-width: 30px; margin-top: -15px; margin-left: -15px;}
.ui-icon.emui-icon-comment-hide {background-image: url([[icon-comment-hide.png]]); min-height: 30px; min-width: 30px; margin-top: -15px; margin-left: -15px;}
.ui-state-default .ui-icon.em-icon-quiz {background-image: url([[icon-multichoicequiz.png]]);}
/**********************************************
* pageTwo - closebutton
**********************************************/
#pageTwo .closepagetwobutton {
position: absolute;
top: 15px;
right: 25px;
padding: 0.2em 1em;
border: 1px solid #a00;
border-radius: 0.3em;
color: white;
font-weight: bold;
text-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5);
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
cursor: pointer;
z-index: 5;
background: rgb(255,48,25); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,48,25,1) 0%, rgba(207,4,4,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,48,25,1)), color-stop(100%,rgba(207,4,4,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3019', endColorstr='#cf0404',GradientType=0 ); /* IE6-9 */
}
#pageTwo .closepagetwobutton:active {
margin-top: 2px;
box-shadow: 2px 0 2px rgba(0,0,0,0.5);
}
dl dd:only-child:before {content: "Tästä sisällöstä pois yksinäinen kaksoispiste!"; display: block; border: 3px solid red; border-radius: 8px 8px 0 0; border-bottom: none; padding: 0.5em 1em;}
dl dd:only-child {border: none; border-bottom: 5px solid red;}
/**********************************************
* Eulexia font
**********************************************/
body.eulexia div#displayArea div.bookpage,
body.eulexia div#displayArea div.bookpage h1,
body.eulexia div#displayArea div.bookpage h2,
body.eulexia div#displayArea div.bookpage h3,
body.eulexia .ui-widget {
font-family: eulexia;
}
/*}}}*/
/*{{{*/
/************************************
* Layout of Ebook
* Petri Salmela
* 11.6.2011
************************************/
/***************
* offline mode
***************/
body.offlineuse .hideoffline,
body.offlineuse #fixEbook,
body:not(.offlineuse) #settingscoursemanagementswitch,
body.offlineuse #bottomrightmenu li.checkUpdates,
body.offlineuse #bottomrightmenu li.personalnote,
body.offlineuse #bottomrightmenu li.openemathcenter,
body.offlineuse .ebookshelf_apps ul.applist li.applistitem[appname="chat"],
body.offlineuse .ebookshelf_apps ul.applist li.applistitem[appname="bookmarks"],
body.offlineuse #indicatorlights ul{
display:none;
}
/***************
* Admin mode
***************/
#tiddlerDisplay {
width: auto;
margin-right: 1em;
margin-left: 1em;
margin-top: 2em;
border: none;
background-color: transparent;
clear: both;
}
.adminmode #tiddlerDisplay {
display: block;
position: fixed;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
width: auto;
margin: 2em;
border: 5px solid red;
z-index: 500;
background-color: white;
box-shadow: 0 0 10px 2px rgba(0,0,0,0.4);
padding: 0.5em;
}
#tiddlerDisplay:hover {
position: fixed;
bottom: 0;
right: 20px;
left: 10px;
height: 80%;
overflow: auto;
}
body.adminmode #backstageButton {display: block!important;}
/*** Tarkista nämä: begin *******/
#tiddlerDisplay .sdbookassignment .ebookoneassignment .command_editSD,
#tiddlerDisplay .sdbookassignment .ebookoneassignment table.sdtable {
display: none;
}
#tiddlerDisplay .sdbookassignment .ebookoneassignment:hover {
position: relative;
}
#tiddlerDisplay .sdbookassignment .ebookoneassignment:hover table.sdtable {
display: block;
position: absolute;
left: 4em;
width: 90%;
border: 1px solid black;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-o-border-radius: 8px;
box-shadow: 3px 3px 3px #333;
-moz-box-shadow: 3px 3px 3px #333;
-webkit-box-shadow: 3px 3px 3px #333;
-o-box-shadow: 3px 3px 3px #333;
}
/*** Tarkista nämä: end *******/
/*****************************************
* Content
*****************************************/
.center {
display: block;
text-align: center;
}
.cblogo {
display: inline-block;
float: left;
}
.eulogo {
display: inline-block;
float: right;
}
.cblogo img, .eulogo img {
height: 50px;
width: auto;
background-color: white;
margin: 0.5em 1.5em;
}
.disclaimer {
display: block;
background-color: white;
text-align: center;
font-family: serif;
font-size: 65%;
margin-top: 2em;
}
.disclaimer:after {
content: " ";
clear: both;
}
.showusername {margin-right: 3em;}
#backstage {
z-index: 120;
}
#backstageButton {display: none!important;}
a#backstageShow,
a#backstageHide {
margin-right: 100px;
}
/******************
* Corner menus
******************/
#leftmenu {
position: fixed;
top: 0;
left: 0;
z-index: 200;
}
#rightmenu {
position: fixed;
top: 0;
right: 0;
z-index: 200;
}
#rightmenu .ebookshelfbutton {
height: 40px;
width: 40px;
border-radius: 0 0 0 40px;
background-color: red;
background: transparent url([[bookshelf-right.png]]) left top no-repeat;
box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
}
#leftmenu .ebookshelfbutton {
height: 40px;
width: 40px;
border-radius: 0 0 40px 0;
background-color: red;
background: transparent url([[bookshelf-left.png]]) left top no-repeat;
box-shadow: 3px 3px 5px rgba(0,0,0,0.5);
}
#leftmenu .ebookshelfwrapper,
#rightmenu .ebookshelfwrapper {
display: none;
min-width: 500px;
max-width: 80em;
}
#leftmenu.menuopen .ebookshelfwrapper,
#rightmenu.menuopen .ebookshelfwrapper {
display: block;
position: absolute;
top: 0;
padding-top: 40px;
margin-right: -30px;
margin-left: -23px;
margin-top: 15px;
}
#leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left.png]]) left top no-repeat;
}
#rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right.png]]) right top no-repeat;
}
#leftmenu .ebookshelfcontainer,
#rightmenu .ebookshelfcontainer {
background-color: white;
border: 4px solid #ff8000;
border-radius: 10px;
box-shadow: 8px 8px 8px #999;
}
#leftmenu .ebookshelfcontainer h1,
#rightmenu .ebookshelfcontainer h1 {
margin: 1em 1em 0 1em;
color: #ff8000;
border-bottom: 3px solid #ff8000;
}
#bottomrightmenu {
position: fixed;
bottom: 0;
right: 0;
z-index: 200;
display: block;
}
#bottomrightmenu .booksettingsmenu {
height: 40px;
width: 40px;
border-radius: 40px 0 0 0;
background: transparent url([[bottommenu-right.png]]) right bottom no-repeat;
display: block;
}
#bottomleftmenu {
position: fixed;
bottom: 0;
left: 0;
z-index: 200;
display: block;
}
#bottomleftmenu .ebookteachertools {
height: 40px;
width: 40px;
border-radius: 0 40px 0 0;
background: transparent url([[bottommenu-left.png]]) left bottom no-repeat;
display: block;
}
#leftmenu.hidemenu div.ebookshelfbutton,
#leftmenu.hidemenu div.ebookshelfwrapper
{display:none;}
/**********************************************************
* Cornermenus
**********************************************************/
.toolmenu {
cursor: pointer;
}
.toolmenu .ebookteachertools.hidden ul,
.toolmenu .booksettingsmenu.hidden ul {
display: none;
}
.toolmenu .ebookteachertools ul,
.toolmenu .booksettingsmenu ul {
display: block;
}
.toolmenu .ebookteachertools ul,
.toolmenu .booksettingsmenu ul {
list-style: none;
position: fixed;
bottom: 30px;
background: white;
border: 1px solid #ddd;
border-radius: 1em;
padding: 0.5em 0;
box-shadow: 4px 4px 4px rgba(0,0,0,0.5);
}
.toolmenu .ebookteachertools ul {
left: 20px;
}
.toolmenu .booksettingsmenu ul {
right: 20px;
}
.toolmenu .ebookteachertools ul li,
.toolmenu .booksettingsmenu ul li {
white-space: nowrap;
padding: 0.3em 1em;
border-top: 2px solid #ddd;
border-bottom: 2px solid #777;
}
.toolmenu .ebookteachertools ul li:hover,
.toolmenu .booksettingsmenu ul li:hover {
background-color: #eee;
cursor: pointer;
}
.ebookteachertools ul.teacherselection,
.booksettingsmenu ul.booksettingsselection {
border: 4px solid orange;
border-top-width: 16px;
}
.ebookteachertools ul.teacherselection li,
.booksettingsmenu ul.booksettingsselection li {
border: 1px solid #aaa;
margin: 0.3em;
border-radius: 0.5em;
}
#bottomleftmenu ul.teacherselection li,
#bottomrightmenu ul.booksettingsselection li {
padding-left: 30px;
}
#bottomrightmenu ul.booksettingsselection li.closebookmenu:before {
content: url([[icon-logout.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.checkUpdates:before {
content: url([[icon-update.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.ebsettingsmenu:before {
content: url([[icon-settings.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.mqpaneltoggle:before {
content: url([[icon-mathpanel.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.presentationopen:before {
content: url([[icon-presentation.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.calculatoropen:before {
content: url([[icon-calculator.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.personalnote:before {
content: url([[icon-feedback.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomrightmenu ul.booksettingsselection li.openemathcenter:before {
content: url([[icon-goemath.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherAdd:before {
content: url([[icon-addelem.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherEdit {
display: none;
}
#bottomleftmenu ul.teacherselection li.teacherEdit:before {
content: url([[icon-edit.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments:before {
content: url([[icon-sethome.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments ul {
position: static;
border: none;
box-shadow: none;
margin: 0;
padding: 0;
background: transparent;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments ul li {
background-color: white;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments ul li:hover {
background-color: #333;
color: white;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments ul li.editHomeassignment:before {
content: url([[icon-edit.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherHomeassignments ul li.newHomeassignment:before {
content: url([[icon-sethome.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherUseStudentView:before {
content: url([[icon-eye.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.teacherChecksolutions:before {
content: url([[icon-checksol.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#bottomleftmenu ul.teacherselection li.studentManagement:before {
content: url([[icon-student.png]]);
width: 20px;
margin-left: -25px;
margin-right: 5px;
vertical-align: top;
}
#studentViewPanel a,
#teachertoolcontrol button {
display: block;
width: 100%;
margin: 0.3em;
}
#studentViewPanel,
#teachertoolcontrol {
background-color: white;
padding: 0.2em 0.7em 0.2em 0;
border-top: 5px solid orange;
border-right: 5px solid orange;
border-radius: 0 1em 0 0;
box-shadow: 5px -5px 5px rgba(0,0,0,0.5);
}
#studentViewPanel {
position: absolute;
bottom: 0;
left: 0;
z-index: 200;
}
/******************
* Book pages
******************/
.bookpage {
max-width: 60em;
font-size: 125%;
padding-bottom: 5em;
}
.bookpage a:hover{
background-color:transparent;
}
.bookpage[types="assignment"]{
max-width: 1200px;
}
.bookpage h1 {
font-size: 200%;
margin-bottom: 1.5em;
}
.bookpage h2 {
font-size: 150%;
margin-bottom: 1.5em;
}
/*.bookpage > span > .ebooktoc {
font-size: 60%;
margin-top: -7em;
background-color: white;
border: 1px solid #777;
float: right;
padding: 0.5em;
border-radius: 8px;
box-shadow: 3px 3px 3px #777;
}
.ebooktoc h1 {font-size: 100%; background-color: black; color: white; margin: 0 0 1em 0; padding: 0.5em; border-radius: 5px 5px 0 0;}
.bookpage .ebooktoc.coursebook {padding: 0;}
.bookpage .ebooktoc.coursebook > ol {margin: 0.5em;}
*/
.bookpage > [tiddler] > [tiddler] {
display: block;
}
#messageWrapper {
display: none;
}
.header {
background-color: rgba(116,134,45,0.9);
z-index: 8000;
}
.headerShadow, .headerForeground {
padding-top: 0.2em;
}
div.tiddler {
position: relative;
padding-bottom: 1em;
margin-bottom: 0;
border: none;
background-color: white;
border: 1px solid #aaa;
}
div.tiddler div.subtitle,
div.tiddler div.tagged {
display: none;
}
span[tiddler^="textelem"] {margin-bottom: 1.5em; margin-top: 1.5em;}
#displayArea {
position: fixed;
top: 1.5em;
bottom: 2em;
left: 0;
margin: 0;
padding-right: 0;
overflow-y: scroll;
width: auto;
height: 0;
background-color: transparent;
}
#contentWrapper[pageopen] #displayArea {
width: 48%;
background: none;
}
#sidePage {
position: absolute;
top: 0;
bottom: 2em;
left: 49.3%;
right: 0;
width: 0;
height: 0;
margin-top: 1.5em;
margin-bottom: -2px;
margin-left: 0;
padding: 0;
overflow: hidden;
background-color: transparent;
border: 1px solid #999;
display: none;
}
#contentWrapper[pageopen] #sidePage {
display: block;
}
#sidebar {
display: none;
position: fixed;
right: 0;
top: 10em;
bottom: 5px;
padding-left: 2em;
padding-right: 3px;
width: 0;
overflow-x: hidden;
overflow-y: hidden;
border: 1px solid black;
border-right: none;
border-radius: 8px 0 0 8px;
-moz-border-radius: 8px 0 0 8px;
-webkit-border-radius: 8px 0 0 8px;
background-color: white;
z-index: 100;
}
#sidebar:hover {
right: 0;
width: auto;
overflow-y: auto;
}
body.adminmode #sidebar {
display: block;
}
#pageOneWrapper {
position: fixed;
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
width: 99%;
padding-top: 6em;
background-color: white;
overflow: auto;
box-shadow: 5px 5px 10px 2px rgba(0,0,0,0.5);
}
#contentWrapper[pageopen] #pageOneWrapper {
width: 49%;
right: auto;
}
#pageTwoWrapper {
width: 0%;
}
#contentWrapper[pageopen] #pageTwoWrapper {
position: fixed;
top: 10px;
bottom: 10px;
right: 10px;
width: 49%;
padding-top: 6em;
background-color: white;
overflow: auto;
box-shadow: 5px 5px 10px 2px rgba(0,0,0,0.5);
}
/***********************
* Book page navigation
***********************/
#pageOneWrapper #pageOneNavi {
position: fixed;
left: 0px;
top: 14px;
width: 90%;
border-radius: 0 5em 5em 0;
border-right: 1px solid black;
border-bottom: 1px solid black;
border-top: 1px solid black;
background-color: #eee;
z-index: 100;
padding: 0 0 0.5em 0.5em;
box-shadow: 5px 5px 5px rgba(0,0,0,0.3);
}
#pageTwoWrapper #pageTwoNavi {
position: fixed;
right: 0px;
top: 14px;
width: 47%;
border-radius: 5em 0 0 5em;
border-left: 1px solid black;
border-bottom: 1px solid black;
border-top: 1px solid black;
background-color: #eee;
z-index: 100;
padding: 0 0 0.5em 0.5em;
box-shadow: 5px 5px 5px rgba(0,0,0,0.3);
}
#contentWrapper[pageopen] #pageOneWrapper #pageOneNavi {
width: 47%;
}
#pageOneWrapper #pageOneNavi,
#pageTwoWrapper #pageTwoNavi {
background: -moz-linear-gradient(top, rgba(255,255,255,0.86) 0%, rgba(255,255,255,0.65) 62%, rgba(255,255,255,0) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.86)), color-stop(62%,rgba(255,255,255,0.65)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,0.86) 0%,rgba(255,255,255,0.65) 62%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,0.86) 0%,rgba(255,255,255,0.65) 62%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,0.86) 0%,rgba(255,255,255,0.65) 62%,rgba(255,255,255,0) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,255,255,0.86) 0%,rgba(255,255,255,0.65) 62%,rgba(255,255,255,0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dbffffff', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
background-color: #afc679;
}
#pageTwoNavi .naviui,
#pageOneNavi .naviui {
padding:0;
margin-top: 1.3em;
}
.pageWrapper .pageNavi .ebooknavibar .navislider {
height: 4px;
}
.ebooknavibar .naviui .navislider .ui-slider-handle {
margin-top: -4px;
}
.ebooknavibar .naviui .navislider .ui-slider-range {
background-image: none;
background-color: red;
}
#pageTwoNavi .ebooknavibar {
margin: 0.5em;
}
.pageNavi:hover .naviui {
display: block;
}
.pageNavi .bcnavi {
margin: 0 0 0.3em 2em;
}
#pageOneNavi .bcnavi {
margin-top: -1em;
}
#pageTwoNavi .bcnavi {
margin-top: -1em;
}
.pageNavi .naviui {
display: block;
}
.pageNavi:hover .bctoc {
display: inline-block;
}
.breadcrumbchapter {
background-color: rgba(255,255,255,0.5);
}
.breadcrumb {
overflow: hidden;
width: 85%;
}
.bcnavi {
white-space: nowrap;
}
.cnavi a {
border-radius: 0.3em;
padding: 0 0.3em;
text-align: center;
margin-left: -0.3em;
margin-top: -0.2em;
}
/**********************************************************
* Authorlist
**********************************************************/
.ebookauthors {
text-align: center;
}
.ebookauthors .ebauthorgroup {
border: 1px solid #ccc;
margin-bottom: 0.2em;
}
.ebookauthors .ebauthorgroup ul {
display: none;
text-align: left;
}
.ebookauthors .ebauthorgroup.showall ul {
display: block;
}
.ebookauthors .ebauthorgroup .ebauthorgroupname {
position: relative;
display: block;
padding: 0.1em 0.5em;
background-color: #4891D9;
color: white;
text-shadow: 1px 1px 1px black;
font-weight: bold;
cursor: pointer;
}
.ebookauthors .secondaryauthors {
margin: 0.5em auto;
max-width: 25em;
}
.ebookauthors .ebauthorgroup .ebauthorgroupname:before {
content: "\25b6";
position: absolute;
display: block;
height: 100%;
width: 1.5em;
font-size: 80%;
background-color: rgba(255,255,255,0.2);
left: 0;
top: 0;
line-height: 1.5em;
}
.ebookauthors .ebauthorgroup.showall .ebauthorgroupname:before {
content: "\25bc";
font-size: 80%;
}
/**********************************************************
* Headers
**********************************************************/
.bookpage[types~="chapter"] h1.ebooktitle[style] {
height: 150px;
position: relative;
border-radius: 10px 10px 0 0;
}
.bookpage h1.ebooktitle[style] {
background-position: center center;
background-repeat: no-repeat;
}
.bookpage[types~="assignment"] h1.ebooktitle[style],
.bookpage[types~="topic"] h1.ebooktitle[style],
.bookpage[types~="section"] h1.ebooktitle[style] {
border-radius: 5px 5px 0 0;
}
.bookpage[types~="chapter"] h1.ebooktitle[style] span {
position: absolute;
display: inline-block;
left: 0.5em;
bottom: 0.5em;
color: white;
text-shadow: 2px 2px 2px black;
}
.bookpage h1.ebooktitle[style] span,
.bookpage[types~="assignment"] h1.ebooktitle[style] span,
.bookpage[types~="topic"] h1.ebooktitle[style] span,
.bookpage[types~="section"] h1.ebooktitle[style] span {
display: inline-block;
padding: 0.1em 0.3em;
margin: 0.1em 0.2em;
color: white;
text-shadow: 2px 2px 2px black;
background-color: rgba(0,0,0,0.3);
border-radius: 0.3em;
}
.bookpage h1.ebooktitle a.headerlink {
display: block;
position: absolute;
right: 0;
bottom: 0;
padding: 1px;
border: 1px solid transparent;
border-radius: 4px;
}
/**********************************************************
* Lists
**********************************************************/
.algorithmlist ol {
border-top: 2px solid black;
border-bottom: 2px solid black;
list-style-position: inside;
padding: 0;
}
.algorithmlist ol li {
padding: 0.2em 1em;
}
.nobulletlist ul {
list-style: none;
}
/**********************************************************
* Solutions
**********************************************************/
.assignmentAccordion0 > .ui-accordion-content {
padding: 1em;
}
.solutionAccordion .ui-accordion-content {
padding: 0.5em;
}
.solutionset {
border: 1px solid #999;
background: white;
padding: 0.5em;
}
.ebelement {position: relative; margin-top: 2em; margin-bottom: 2em;}
.ebelement .removesolelem {
position: absolute;
top: 0;
right: 0;
width: 25px;
height: 25px;
background: white url([[icon-trash-red.png]]) left top no-repeat;
text-align: center;
vertical-align: middle;
display: inline-block;
border: 1px solid #ddd;
}
.ebelement .removesolelem a {
color: transparent;
display: inline-block;
background-color: transparent;
width: 25px;
height: 25px;
margin:0;
padding:0;
}
.ebelement .removesolelem a:hover {
box-shadow: 0 0 5px #f00;
}
.solutiontoolbar {
margin: 0.8em 0 3em 0;
}
.solutionsendtoolbar,
.solutionedittoolbar,
.solutionTeachertoolbar {
text-align: right;
}
.solutionsendtoolbar .sendsolution,
.solutionedittoolbar .editsolution,
.solutionTeachertoolbar button {
text-align: left;
}
.evaluating .solutionTeachertoolbar .markSolution,
.evaluating .solutionTeachertoolbar .makeModelsolution {
display: none;
}
.evaluateMe {
color: red;
font-weight: bold;
text-align: center;
display: inline-block;
margin-left: 1em;
}
.ebelement .sdbooksoltext > span > span.mathquill-textbox,
.solutionanswer span.solutionanswerbox {
display: block;
box-shadow: inset 1px 1px 2px #aaa;
background-color: #fefefe;
}
.ebelement .sdbooksoltext > span > span.mathquill-textbox {
padding: 0.5em 1em 0.5em 0.5em;
margin: 2em 0;
}
.solutiontabs {
margin: 0;
}
.solutiontabs ul.solutiontablist {
margin: 0;
padding: 0;
}
.solutiontabs ul.solutiontablist li {
display: inline-block;
padding: 0;
border-radius: 0.5em 0.5em 0 0;
box-shadow: 5px 5px 5px rgba(0,0,0,0.5);
margin-right: -0.3em;
}
.solutiontabs ul.solutiontablist li.currenttab {
}
.solutiontabs ul.solutiontablist li a {
display: inline-block;
padding: 0.3em 1em;
background-color: white;
border: 1px solid #777;
border-bottom: none;
border-radius: 0.5em 0.5em 0 0;
}
.solutiontabs ul.solutiontablist li.currenttab a {
position: relative;
z-index: 4;
background-color: #eee;
border-color: black;
background-color: #eee;
border-bottom: 1px solid #eee;
margin-bottom: -1px;
border-radius: 0.6em 0.6em 0 0;
}
.solutiontabs ul.solutiontablist li a:hover {
color: black;
}
.solutioncontent {
position: relative;
border: 1px solid black;
background-color: #eee;
padding: 0.1em;
margin: 0;
z-index: 3;
box-shadow: 5px 5px 5px rgba(0,0,0,0.5);
}
.solutionAnswer, .solutionsAnswer {display: block; margin-top: 1em;}
.solutionAnswer:before,
.solutionsAnswer:before {
content: "Answer:";
display: block;
text-decoration: underline;
font-weight: bold;
}
.solutionAnswer:lang(fi):before,
.solutionsAnswer:lang(fi):before {
content: "Vastaus:";
}
.solutionAnswer:lang(sv):before,
.solutionsAnswer:lang(sv):before {
content: "Svar:";
}
.solutionAnswer:lang(et):before,
.solutionsAnswer:lang(et):before {
content: "Vastus:";
}
.teacherassignmentSolution {margin-top: 1em;}
.teacherassignmentSolution button {margin-left: 1em;}
.teacherassignmentSolution.hidden .hideTeacherAssignmentSolution,
.teacherassignmentSolution.hidden .assignmentSolution.solutionAnswer {display: none;}
.teacherassignmentSolution .answerString {text-transform: lowercase;}
.teacherassignmentSolution.hidden .answerString {text-transform: none;}
.assignmentSolution.solutionAnswer {margin: 1em; padding: 0.5em 1em; border: 1px solid #aaa; border-radius: 4px; background-color: rgba(255,255,255,0.5);}
.elemsortable .solutionset .ui-state-highlight {
height: 100px; margin-top: 1em;
}
.elemsortable .ebelement {
max-height: 100px;
overflow: hidden;
border: 2px solid #999;
border-left: 10px solid #555;
border-bottom: 1px dashed #aaa;
margin-top: 1em;
background-color: #fff0f0;
}
button.orderready,
button.ordercancel,
.elemsortable button.ordersolutions,
.elemsortable button.sendsolution,
.elemsortable button.savesolution,
.elemsortable .teachertoolbar,
.elemsortable .solutiontoolbar,
.elemsortable .removesolelem {
display: none;
}
.elemsortable button.orderready,
.elemsortable button.ordercancel {
display: inline-block;
}
.ordershade {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 30;
background-color: transparent;
}
#pageTwo .emptySolution button.startSolution,
#pageTwo .solutionTeachertoolbar,
#pageTwo .solutionsendtoolbar button,
#pageTwo .solutiontoolbar button,
#pageTwo .ebelement a.button.command_qededit,
#pageTwo .ebelement .removesolelem
{display: none;}
#pageTwo .solutionsetwrapper {
position: relative;
}
#pageTwo .solutionsetwrapper .solutionsendtoolbar {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.solutionsettoolbar, .modelsolutionsettoolbar {text-align: right;}
.solutionsubtoolbar, .modelsolutionsubtoolbar {display: inline-block;}
.solutionsubtoolbar button.ebook-button, .modelsolutionsubtoolbar button.ebook-button {min-height: 40px;}
.evaluating .solutionsubtoolbar,
.elemsortable .solutionsubtoolbar,
.solutionordermodebar.solutionsubtoolbar,
.evaluating .modelsolutionsubtoolbar,
.elemsortable .modelsolutionsubtoolbar,
.modelsolutionordermodebar.modelsolutionsubtoolbar {
display: none;
}
.evaluating .solutionTeachertoolbar.solutionsubtoolbar,
.elemsortable .solutionordermodebar.solutionsubtoolbar,
.evaluating .modelsolutionTeachertoolbar.modelsolutionsubtoolbar,
.elemsortable .modelsolutionordermodebar.modelsolutionsubtoolbar {
display: inline-block;
}
.solutionset .ebelement div.structuredderivation div.qededitorbuttons a.button.command_qedclose,
.modelsolutionset .ebelement div.structuredderivation div.qededitorbuttons a.button.command_qedclose
{display: none;}
.solutionset .solutiontoolbar,
.modelsolutionset .modelsolutiontoolbar {
text-align: center;
background-color: #eee;
padding: 4px;
border-radius: 8px;
box-shadow: inset 0 5px 5px rgba(255,255,255,0.5), inset 0 -5px 5px rgba(0,0,0,0.3);
border: 1px solid #888;
position: relative;
padding-left: 2.34em;
margin: 0.8em 0 1.5em 0;
}
.solutionset .solutiontoolbar:before,
.modelsolutionset .modelsolutiontoolbar:before {
content: "+";
background-color: rgba(0,128,0,0.8);
background-color: transparent;
color: black;
text-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,1);
position: absolute;
left:0;
top: 0;
bottom: 0;
font-size: 180%;
font-weight: bold;
border-radius: 8px 0 0 8px;
box-shadow: inset 0 5px 5px rgba(255,255,255,0.5), inset 0 -5px 5px rgba(0,0,0,0.3);
box-shadow: none;
text-align: center;
width: 1.3em;
line-height: 48px;
border-right: 1px solid #999;
}
/**********************************************************
* Solution markings
**********************************************************/
.sdafterbuttons .checkmark {
text-align: center;
font-weight: bold;
margin: 0;
display: inline-block;
border: 1px solid black;
box-shadow: 0 0 2px #aaa;
border-radius: 3px;
text-shadow: 1px 1px 2px #777;
width: 1.2em;
background-color: white;
}
.sdafterbuttons .checkmark.sdwrong {color: red;}
.sdafterbuttons .checkmark.sdcorrect {color: green;}
.manualcheck {position: relative;}
.manualcheck .checkcomment {
position: absolute;
top: -0.5em;
right: 1.5em;
width: 13em;
border: 1px solid #777;
background-color: #ffa;
box-shadow: 2px 2px 3px #555;
display: none;
padding: 0.3em;
}
.manualcheck:hover .checkcomment {
display: block;
}
.sdmanualcheckbox {
vertical-align: middle;
}
.sdmanualcheckbox.sdactive {
position: absolute;
right: 0;
padding: 0.1em;
white-space:nowrap;
border: 1px solid #777;
box-shadow: 0 0 4px #999;
border-radius: 4px;
background: rgb(238,238,238); /* Old browsers */
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
.sdmanualcheckbox span,
.sdmanualcheckbox input,
.sdmanualcheckbox button {
display: none;
}
.sdmanualcheckbox .sdcorrectionmarks {display: inline;}
.sdmanualcheckbox .selected {display: inline;}
.sdmanualcheckbox.sdactive span,
.sdmanualcheckbox.sdactive input,
.sdmanualcheckbox.sdactive button {
display: inline-block;
}
.sdmanualcheckbox .sdwrong,
.sdmanualcheckbox .sdcorrect,
.sdmanualcheckbox .sdnote,
.sdmanualcheckbox .sdempty {
text-align: center;
font-weight: bold;
padding: 0 0.3em;
margin: 1px;
width: 1.2em;
color: #777;
text-shadow: 0 0 3px white;
background: transparent;
}
.sdmanualcheckbox .sdwrong:hover,
.sdmanualcheckbox .sdcorrect:hover,
.sdmanualcheckbox .sdnote:hover,
.sdmanualcheckbox .sdempty:hover {
margin: 0;
cursor: pointer;
background-color: #ececec;
border: 1px solid #777;
border-radius: 3px;
}
.sdmanualcheckbox .selected {
margin: 0;
display: inline-block;
border: 1px solid black;
box-shadow: 0 0 2px #aaa;
border-radius: 3px;
text-shadow: 1px 1px 2px #777;
background: rgb(238,238,238); /* Old browsers */
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
.sdmanualcheckbox .sdwrong.selected {color: red;}
.sdmanualcheckbox .sdcorrect.selected {color: green;}
.sdmanualcheckbox .sdnote.selected {color: blue;}
.sdmanualcheckbox .sdempty.selected {color: black;}
.sdmanualcheckbox input.hideinput {
visibility: hidden;
}
.sdcorrectionmarks .selected span {display: inline-block;}
[lang="fi"] .sdcorrectionmarks .sdcorrect:before,
[lang="fi"] .sdafterbuttons .checkmark.sdcorrect:before {
content: '\2052';
}
[lang="fi"] .sdcorrectionmarks .sdwrong:before,
[lang="fi"] .sdafterbuttons .checkmark.sdwrong:before {
content: '\2714';
}
[lang="fi"] .sdcorrectionmarks .sdcorrect span,
[lang="fi"] .sdafterbuttons .checkmark.sdcorrect span {
display: none;
}
[lang="fi"] .sdcorrectionmarks .sdwrong span,
[lang="fi"] .sdafterbuttons .checkmark.sdwrong span {
display: none;
}
[lang="sv"] .sdcorrectionmarks .sdcorrect:before,
[lang="sv"] .sdafterbuttons .checkmark.sdcorrect:before {
content: 'R';
}
[lang="sv"] .sdcorrectionmarks .sdwrong:before,
[lang="sv"] .sdafterbuttons .checkmark.sdwrong:before {
content: '\2714';
}
[lang="sv"] .sdcorrectionmarks .sdcorrect span,
[lang="sv"] .sdafterbuttons .checkmark.sdcorrect span {
display: none;
}
[lang="sv"] .sdcorrectionmarks .sdwrong span,
[lang="sv"] .sdafterbuttons .checkmark.sdwrong span {
display: none;
}
.generalfeedback:before {font-weight: bold; display: block; content: "Teacher's feedback:"; background-color: #ff5; padding: 0.1em 0.5em; border-radius: 5px 5px 0 0;}
:lang(fi) .generalfeedback:before {content: "Opettajan palaute:";}
:lang(sv) .generalfeedback:before {content: "Lärarens feedback:";}
:lang(et) .generalfeedback:before {content: "Õpetaja tagasiside:";}
.generalfeedback {border: 1px solid black; border-radius: 3px; background: #ffa; padding: 0; margin: 1em 0;}
.generalfeedback p {margin: 0.5em;}
.generalfeedback .mathquill-textbox {display: block; margin: 0.5em; background-color: white; padding: 0.3em;}
.solutionset > span > div[loc] {
display: block;
text-align: right;
margin-bottom: 0;
height: 0;
z-index: 40;
position: absolute;
right: 1em;
left: 2em;
margin-top: -2em;
}
.solutionset > span > div[loc] .sdafterbuttons {margin-top: -1.5em; display: block;}
.solutionset > span > div[loc] .sdafterbuttons .checkmark {border-radius: 50%; font-size: 160%; box-shadow: 2px 2px 2px rgba(0,0,0,0.5);}
.solutionset > span > div[loc] .sdafterbuttons .checkcomment {text-align: left;}
/**********************************************
* Home assignments
**********************************************/
/*.teacherAccordions h3.homeassignment:after ,*/
/*.sdbookassignmentlist h3.homeassignment:after {*/
/* content: "";*/
/* background: transparent url([[icon-home.png]]) left top no-repeat;*/
/* width: 20px;*/
/* height: 19px;*/
/* position: absolute;*/
/* right: 10px;*/
/* top: 8px;*/
/*}*/
.teacherAccordions h3 .markinghomeassignment,
.sdbookassignmentlist h3 .markinghomeassignment {
height: 0;
}
.teacherAccordions h3 .markinghomeassignment a span,
.sdbookassignmentlist h3 .markinghomeassignment a span {
display: none;
}
.teacherAccordions h3.homeassignment span svg.mini-icon-home,
.sdbookassignmentlist h3.homeassignment span svg.mini-icon-home,
.teacherAccordions h3 div.markinghomeassignment a svg.mini-icon-home,
.sdbookassignmentlist h3 div.markinghomeassignment a svg.mini-icon-home{
position: absolute;
right: 10px;
top: 8px;
}
.teacherAccordions h3.oldHomeassignment span svg.mini-icon-home,
.sdbookassignmentlist h3.oldHomeassignment span svg.mini-icon-home {
position: absolute;
right: 5px;
top: 4px;
}
.teacherAccordions h3 svg.mini-icon-home * ,
.sdbookassignmentlist h3 svg.mini-icon-home * {
fill: #aaa;
}
.teacherAccordions h3.oldHomeassignment span svg.mini-icon-home,
.sdbookassignmentlist h3.oldHomeassignment span svg.mini-icon-home {
width: 15px;
height: 15px;
}
.teacherAccordions h3 div.markinghomeassignment a svg.mini-icon-home,
.sdbookassignmentlist h3 div.markinghomeassignment a svg.mini-icon-home,
.teacherAccordions h3.homeassignment .markinghomeassignment a svg.mini-icon-home,
.sdbookassignmentlist h3.homeassignment .markinghomeassignment a svg.mini-icon-home {
position: absolute;
right: 20px;
top: 8px;
}
h3.homeassignment[homeassignmenttype="0"] svg.mini-icon-home * {fill: black;}
h3.homeassignment[homeassignmenttype="1"] svg.mini-icon-home * {fill: red;}
h3.homeassignment[homeassignmenttype="2"] svg.mini-icon-home * {fill: blue;}
h3.homeassignment[homeassignmenttype="3"] svg.mini-icon-home * {fill: green;}
h3.homeassignment[homeassignmenttype="4"] svg.mini-icon-home * {fill: violet;}
h3.homeassignment[homeassignmenttype="0"] a svg.mini-icon-home * {fill: black;}
h3.homeassignment[homeassignmenttype="1"] a svg.mini-icon-home * {fill: red;}
h3.homeassignment[homeassignmenttype="2"] a svg.mini-icon-home * {fill: blue;}
h3.homeassignment[homeassignmenttype="3"] a svg.mini-icon-home * {fill: green;}
h3.homeassignment[homeassignmenttype="4"] a svg.mini-icon-home * {fill: violet;}
h3.oldHomeassignment[oldtype="0"] span svg.mini-icon-home * {fill: black;}
h3.oldHomeassignment[oldtype="1"] span svg.mini-icon-home * {fill: red;}
h3.oldHomeassignment[oldtype="2"] span svg.mini-icon-home * {fill: blue;}
h3.oldHomeassignment[oldtype="3"] span svg.mini-icon-home * {fill: green;}
h3.oldHomeassignment[oldtype="4"] span svg.mini-icon-home * {fill: violet;}
.teacherAccordions h3 .markhomeassignment ,
.sdbookassignmentlist h3 .markhomeassignment {
position: absolute;
right: 10px;
top: 8px;
height: 20px;
widht: 20px;
padding: 0;
margin: 0;
z-index: 300;
}
.teacherAccordions h3 .markhomeassignment a ,
.sdbookassignmentlist h3 .markhomeassignment a {
display: block;
margin: 0;
height: 20px;
width: 20px;
padding: 0;
background: transparent url([[icon-home-inactive.png]]) left top no-repeat;
}
.teacherAccordions h3.homeassignment .markhomeassignment a ,
.sdbookassignmentlist h3.homeassignment .markhomeassignment a {
background: transparent url([[icon-home.png]]) left top no-repeat;
}
.teacherAccordions h3 .markhomeassignment a span ,
.sdbookassignmentlist h3 .markhomeassignment a span {
display: none;
}
#homeColors {
position:fixed;
top: 30px;
left: 15px;
min-heigth: 30px;
min-width: 30px;
border: 1px solid #666;
background-color: white;
padding: 2px;
border-radius: 4px;
box-shadow: 5px 5px 5px rgba(0,0,0,0.5);
background: rgb(238,238,238); /* Old browsers */
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
#homeColors ul {
margin: 0;
padding: 0;
list-style: none;
line-height: 30px;
}
#homeColors ul li {
display: inline-block;
cursor: pointer;
border-radius: 4px;
border: 1px solid #666;
margin: 2px;
padding: 1px;
width: 34px;
height: 34px;
vertical-align: middle;
text-align: center;
box-shadow: -1px -1px 1px rgba(0,0,0,0.4), inset 1px 1px 1px rgba(255,255,255,0.4), inset -1px -1px 1px rgba(0,0,0,0.4), 1px 1px 1px rgba(255,255,255,0.4);
background: rgb(238,238,238); /* Old browsers */
background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* IE6-9 */
}
#homeColors ul li.selected {
background: white;
border: 1px solid red;
}
#homeColors ul li.selected svg {
width: 30px;
height: 30px;
}
#homeColors ul li svg {
vertical-align: middle;
width: 20px;
height: 20px;
transition: width 1s, height 1s;
-webkit-transition: width 1s, height 1s;
}
#homeColors ul li[homeassignmenttype="0"] svg path {
fill: black;
}
#homeColors ul li[homeassignmenttype="1"] svg path {
fill: red;
}
#homeColors ul li[homeassignmenttype="2"] svg path {
fill: blue;
}
#homeColors ul li[homeassignmenttype="3"] svg path {
fill: green;
}
#homeColors ul li[homeassignmenttype="4"] svg path {
fill: violet;
}
.sdbooktheory img {
height: auto;
max-width: 92%;
}
.ebookbox .sdbooktheory .functiongraph {
border: none;
}
div.tiddler div.viewer {
padding-left: 20px;
padding-right: 5px;
magrin-left: 20px;
margin-right: 20px;
}
.tiddler.selected {
position: relative;
}
div.tiddler[tags~=sdbookchapter] div.title,
div.tiddler[tags~=EbookChapter] div.title,
div.tiddler[tags~=EbookSubsection] div.title {
color: black;
text-shadow: 1px 1px 2px #555;
font-size: 250%;
font-family: serif;
text-align: left;
border: none;
padding-bottom: 21px;
background: transparent url([[h1line.png]]) left bottom no-repeat;
}
div.tiddler[tags~=EbookSubsection] div.title {
font-size: 200%;
}
.mathdisplaystyle {
text-align: center;
font-size: 100%;
margin: 1em 0;
}
span.solutionbuttons {
display: block;
position: relative;
background: transparent url([[button-bg.png]]) left bottom repeat-x;
border-radius: 8px;
min-height: 24px;
}
span.solutionbuttons a.sdbookbutton {
display: inline-block;
margin: 0 5px;
padding: 0 1em;
font-size: 120%;
font-weight: bold;
height: 2.5em;
}
span.solutionbuttons a.sdbookbutton span {
vertical-align: middle;
}
span.solutionbuttons a.sdbookbutton:hover {
background: transparent url([[button-bg.png]]) left top repeat-x;
color: black;
}
span.solutionbuttons .sdbookbuttonmid {
display: inline-block;
border-left: 1px solid black;
border-right: 1px solid white;
width: 1px;
position: relative;
top: 0;
bottom: 0;
}
/********* mathquill: text vs. math ****************/
.mathquill-textbox.mathquill-editable.hasCursor,
.mathquill-editable.mathquill-rendered-math .hasCursor.text {
-webkit-box-shadow: green 0 0 3px 2px;
-moz-box-shadow: green 0 0 3px 2px;
box-shadow: green 0 0 3px 2px;
}
.qededitor {
clear: both;
}
/****************************************************
* Ebookboxes
****************************************************/
.ebookbox {
font-size: 100%;
margin: 2.5em 0;
clear: both;
position: relative;
}
.ebookbox .ebookboxnumber {
text-decoration: underline;
margin-right: 1em;
}
.ebookbox br {display: block;}
.ebookbox .qededitor {
margin: 1.5em 0.2em;
}
.ebookbox h1 {
font-size: 140%;
padding: 0.1em 0.5em;
text-align: left;
}
.ebookbox h1 span.ebookboxnumber {
font-size: 75%;
}
.ebookbox .sdbookexample,
.ebookbox .sdbooktheory {
background-color: #fafafa;
box-shadow: 5px 5px 5px #ccc;
margin: 0 auto;
max-width: 60em;
}
.ebookbox .sdbooktheory {
margin: 0 2em;
}
.ebookbox .sdbookexample:after,
.ebookbox .sdbooktheory:after,
.ebookbox .sdbookdiscussion:after
{content: " "; clear: both; display: block; border: none;}
.ebookbox .sdbookexample h1 {border-bottom: 1px solid #aaa;}
.ebookbox .sdbooktheory h1 {border-bottom: 1px solid #aaa;}
.ebookbox .sdbookexample .functiongraph {border: none;}
.ebookbox .sdbookexample h2 {font-family: sans; font-size: 110%; margin-top: 3em;}
.ebookbox .button.command_qededit,
.ebookbox .qededitorbuttons .button.command_qedclose.command_editorclose {display: none;}
.ebookbox .assigmentSolution .button.command_qededit,
.ebookbox .assigmentSolution .qededitorbuttons .button.command_qedclose.command_editorclose {display: inline-block;}
body.adminmode .ebookbox .button.command_qededit,
body.adminmode .ebookbox .qededitorbuttons .button.command_qedclose.command_editorclose {display: inline-block;}
.ebookbox .sdbookprerequisites {
margin-right: 8em;
margin-left: 0em;
position: relative;
padding: 5px 0.5em 0 0.5em;
max-width: 60em;
}
.ebookbox .sdbookprerequisites h1 {border-bottom: 2px solid black; margin: 1em 0 0.5em 0;}
.ebookbox .sdbookprerequisites ul {border-left: 10px solid black;}
.ebookbox .sdbookdiscussion {
position: relative;
margin: 0 1em;
border: 1px solid #aaa;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-o-border-radius: 8px;
box-shadow: 5px 5px 5px #eee;
padding: 5px 0.5em 0 0.5em;
max-width: 60em;
}
.ebookbox .sdbookdiscussion h1:after {
display: block;
height: 48px;
width: 50px;
position: absolute;
top: -15px;
right: -15px;
background: transparent url([[icon-discussion.png]]) center center no-repeat;
content: " ";
}
.ebookbox .sdbookdiscussion h1 {border: none; margin: 1em 0 0.5em 0;}
.ebookbox .sdbookdiscussion ol > li {margin-bottom: 1.5em;}
.ebookbox .sdbookdiscussion ol > li > ol > li {margin-bottom: 0.3em;}
.ebookbox .sdbookexamplesd {margin-left: 0em; padding: 0; display: block;}
/****
* History
*****/
.ebookbox .sdbookhistory {
border-top: 4px double #333;
margin: 0;
border: 30px solid #e3cba4;
border-width: 30px 33px 30px 30px;
-moz-border-image: url([[background-paper.png]]) 30 33 30 30 fill repeat stretch;
-webkit-border-image: url([[background-paper.png]]) 30 33 30 30 fill repeat stretch;
border-image: url([[background-paper.png]]) 30 33 30 30 fill repeat stretch;
padding: 0 1em;
}
.ebookbox .sdbookhistory h1 {
text-align: center;
padding: 0.2em 0.5em 0.5em 0.5em;
margin: 0;
margin-bottom: 1em;
border: none;
text-shadow: 5px 5px 5px black;
background: none;
text-shadow: 2px 2px 3px black;
text-shadow: 2px 2px 3px white;
color: black;
}
.ebookbox .sdbookhistory:after {
content: " ";
clear: both;
display: block;
}
.ebookbox .sdbookhistory .ebookimage {
border: none;
}
/****
* Did you know
*****/
.sdbookdidyouknow h1:before {
display: inline-block;
width: 40px;
height: 40px;
background: transparent url([[icon-idea.png]]) left top no-repeat;
content: "";
margin-right: 1em;
margin-top: 0.5em;
}
.sdbookdidyouknow {box-shadow: 0 0 10px gold;
border-radius: 2em;
padding: 0 1em 0.2em 1em;
}
.sdbookdidyouknow h1 {
margin-top: 0;
}
.sdbookdidyouknow:hover h1:before {
box-shadow: 0 0 10px gold;
}
.sdbookdidyouknow {
box-shadow: none;
border-radius: 2em;
padding: 0 1em 0.2em 1em;
background-color: #f7f7f7;
border: 1px solid #e0e0e0;
}
/****************************************************
* Assignments
****************************************************/
.assignment_text {
margin-bottom: 1.5em;
}
.assignmentLevel0 > h2:before {
content: "\0272a";
}
.assignmentLevel1 > h2:before {
content: "\0272a\0272a";
}
.assignmentLevel2 > h2:before {
content: "\0272a\0272a\0272a";
}
.assignmentLevel0 > h2:before,
.assignmentLevel1 > h2:before,
.assignmentLevel2 > h2:before {
font-weight: bold;
padding-left: 1em;
text-shadow: 0 0 3px gold;
color: #c00;
font-size: 150%;
}
.assignmentId {
display: none;
}
/****************************************************
* Ebook pages
****************************************************/
#pageOne, #pageTwo {
margin: 0.5em auto;
padding: 0 0.5em;
}
/*
#pageOne {
margin-left: 1.3em;
}
#pageTwo {
margin-right: 1.3em;
}
*/
.ebooknavibar {
text-align: center;
}
#pageTwoWrapper .ebooknavibar {
margin-top: -0.8em;
}
.hideNavi .pageNavi {
display: none;
}
.ebooknavibar .navibuttonset {
float: left;
margin-left: 2em;
margin-top: -2em;
margin-right: 4em;
font-size: 70%;
}
.ebooknavibar a.naviprev {
display: inline-block;
padding-top: 20px;
width: 5em;
text-align: center;
background: transparent url([[prevpage.png]]) center top no-repeat;
}
.ebooknavibar a.navinext {
display: inline-block;
padding-top: 20px;
width: 5em;
text-align: center;
background: transparent url([[nextpage.png]]) center top no-repeat;
}
.ebooknavibar a.naviup {
display: inline-block;
padding-top: 20px;
width: 5em;
text-align: center;
background: transparent url([[uppage.png]]) center top no-repeat;
}
.ebooknavibar .navibuttonset button {
padding: 5px 0 7px 0;
width: 30px;
}
.ebooknavibar .navibuttonset .ui-button-text span {
display: none;
}
.ebooknavibar .showusername {
text-align: right;
display: none;
}
.ebooknavibar .bcnavi {
position: relative;
text-align: left;
margin-top: 1.5em;
margin-left: 2.5em;
}
.ebooknavibar .bcnavi .bctoc {
display: inline-block;
width: 50px;
height: 34px;
margin-right: 0.8em;
vertical-align: bottom;
background: transparent url([[book-icon.png]]) left top no-repeat;
cursor: pointer;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li > ul.subtoc {
display: none;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li {
position: relative;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li:hover > ul.subtoc {
display: block;
padding: 0.3em;
border: 1px solid #999;
border-radius: 4px;
position: absolute;
top: 1em;
left: 8em;
background-color: white;
z-index: 1000;
box-shadow: 5px 5px 5px #999;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li:hover > ul.subtoc,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li:hover > ul.subtoc {
display: block;
padding: 0.3em;
border: 1px solid #999;
border-radius: 4px;
position: absolute;
top: 1em;
left: 8em;
background-color: white;
z-index: 1000;
box-shadow: 5px 5px 5px #999;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc {
display: none;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li {
position: relative;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc li:hover,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc li:hover {
background-color: #aaf;
color: black;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc li:hover > a,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc li:hover > a {
background-color: transparent;
color: black;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc li > .tocitemnumber,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc li > .tocitemnumber {
float: left;
margin-right: 0.5em;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc li > a,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc li > a {
display: block;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > a {
margin-left: 1em;
}
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li > a,
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li > a,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li > a {
margin-left: 2em;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li > ul.subtoc > li > a,
.ebooknavibar .subtocwrapper > .subtocinner > ul.subtoc > li > ul.subtoc > li > ul.subtoc > li > a {
margin-left: 3em;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li,
.ebooknavibar .bctoc .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li:hover > ul.subtoc > li,
.ebooknavibar .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li,
.ebooknavibar .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li:hover > ul.subtoc > li {
padding: 0 1em;
}
.ebooknavibar .bctoc .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc,
.ebooknavibar .bctoc .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li:hover > ul.subtoc,
.ebooknavibar .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc,
.ebooknavibar .subtocwrapper > .subtocinner ul.subtoc > li:hover > ul.subtoc > li:hover > ul.subtoc {
padding: 0.5em 0;
}
.ebooknavibar .breadcrumb {
display: inline-block;
text-align: left;
font-size: 100%;
margin-right: 50px;
}
.ebooknavibar .breadcrumb .breadcrumbnumber {
min-width: 2.5em;
display: inline-block;
text-align: right;
font-weight: bold;
font-size: 130%;
}
.ebooknavibar .breadcrumb .breadcrumbchapter {
display: inline-block;
border: 1px solid #999;
border-radius: 4px;
padding: 0.1em;
margin: 0;
}
.ebooknavibar .breadcrumb .breadcrumbchapter:hover {
cursor: pointer;
box-shadow: 0 0 5px #777;
border-radius: 4px;
}
.ebooknavibar .breadcrumb .breadcrumbchapter:last-child {
text-decoration: underline;
}
.ebooknavibar .breadcrumb .breadcrumbchapter + .breadcrumbdelimiter + .breadcrumbchapter + .breadcrumbdelimiter + .breadcrumbchapter {
border: none;
}
.ebooknavibar .breadcrumb .breadcrumbchapter + .breadcrumbdelimiter + .breadcrumbchapter + .breadcrumbdelimiter + .breadcrumbchapter:hover {
box-shadow: none;
cursor: auto;
}
.ebooktoc ol > li {
font-size: 100%;
font-weight: bold;
counter-increment: root;
}
.ebooktoc ol > li > ol {
padding-left: 0;
counter-reset: subsection;
list-style-type: none;
}
.ebooktoc ol > li > ol > li {
counter-increment: subsection;
padding-left: 3em;
}
.ebooktoc ol > li > ol > li:before {
content: counter(root) "." counter(subsection) " ";
margin-left: -3em;
padding-left: 20px;
float: left;
width: 3em;
}
.ebooktoc ol > li > ol > li.hassubsections:before {
background: transparent url([[angle-right.png]]) left top no-repeat;
}
.ebooktoc ol > li > ol > li.hassubsections.subshow:before {
background: transparent url([[angle-down.png]]) left top no-repeat;
}
.ebooktoc ol > li > ol > li > ol {
padding-left: 0;
counter-reset: subsubsection;
list-style-type: none;
}
.ebooktoc ol > li > ol > li > ol > li {
counter-increment: subsubsection;
padding-left: 3em;
}
.ebooktoc ol > li > ol > li > ol > li:before {
content: counter(root) "." counter(subsection) "." counter(subsubsection) " ";
margin-left: -3em;
padding-left: 20px;
float: left;
width: 3em;
}
.ebooktoc.exercises ol > li {
font-size: 100%;
font-weight: bold;
counter-increment: root;
}
.ebooktoc.exercises ol > li > ol {
padding-left: 0;
counter-reset: subsection;
list-style-type: none;
}
.ebooktoc.exercises ol > li > ol > li {
counter-increment: subsection;
padding-left: 0;
}
.ebooktoc.exercises ol > li > ol > li:before {
content: counter(subsection) " ";
}
.ebooktoc.exercises ol > li > ol > li > ol {
padding-left: 1.5em;
counter-reset: subsubsection;
list-style-type: none;
display: inline;
}
.ebooktoc.exercises ol > li > ol > li > ol > li {
counter-increment: subsubsection;
padding-left: 0;
display: inline;
}
.ebooktoc.exercises ol > li > ol > li > ol > li:before {
content: "";
}
.ebooktoc.hidesub ol > li > ol > li.subshow {
/* box-shadow: 0 0 2px black; */
}
.ebooktoc.hidesub ol > li > ol > li > ol {
display: none;
}
.ebooktoc.hidesub ol > li > ol > li.subshow ol {
display: block;
}
.ebooktoc.coursebook h1 {margin-bottom: 0; border-bottom: 0;}
.ebooktoc.coursebook h2 a {color: black;}
.ebooktoc.coursebook h2 a:hover {background-color: transparent;}
.ebooktoc.coursebook h2 {background-color: #ccc; color: black; font-size: 100%; margin: 0; padding: 0.5em; margin-bottom: 0.5em;}
.ebooktoc.coursebook span + h2 {border-radius: 8px 8px 0 0;}
.ebooktoc.coursebook {min-width: 15em; max-width: 25em;}
#mainMenu .ebooktoc.coursebook {min-width: none; max-width: none;}
.ebooktoc.coursebook h1 + span + h2 {border-radius: 0 0 0 0;}
/****************************************************
* Ebook colors
****************************************************/
.color_red {color: #a00;}
.color_blue {color: #00a;}
.color_green {color: #0a0;}
.color_violet {color: #a0a;}
.color_black {color: #000;}
.color_orange {color: #ff8000;}
.bgcolor_pink {background-color: #fcc;}
/****************************************************
* Ebook navigation
****************************************************/
.ebooknavibar button span.ui-icon {
position: static;
margin: 0.5em auto 0 auto;
}
.ebooknavibar button span.ui-button-text {
padding: 0 0.5em;
min-width: 3em;
}
.ebooknavibar .navislider {
margin: 1em 10px 3px 8.5em;
}
.ebooknavibar .chapstop {position: absolute; top:-10px; bottom: 0px; width: 2px; background-color: blue;}
.ebooknavibar .chapstop .cnavi {position: absolute; top: -0.8em; left: -0.2em;}
.ebooknavibar .chapstop .cnavi span.ctitletext {display: none;}
.ebooknavibar .chapstop .cnavi:hover span.ctitletext {display: block; position: absolute; left: 1.2em; top: 0; background-color: #ffa; z-index: 8000; padding: 0.3em;}
.ebooknavibar .chapstop .cnavi a {background-color: white; font-weight: bold;}
.ebooknavibar .chapstop .cnavi a:hover {background-color: white; color: red;}
/**********************************
***** theory shuffle **************
**********************************/
.theory_shuffle_header,
.theory_shuffle_add,
.theory_shuffle_text{
display:none;
}
.theory_shuffle_clearer{
clear:both;
}
.theory_shuffle_text{
clear:both;
display:none;
}
.theory_shuffle_box{
font-size:110%;
}
.theory_shuffle_box .question_box ul,
.theory_shuffle_box .answer_box ul{
list-style-type: none;
margin: 0;
padding: 0;
float: left;
}
.theory_shuffle_box .question_box ul{
margin-left:200px;
}
.theory_shuffle_box .question_box ul li {
text-align:right;
}
.theory_shuffle_box .answer_box ul li {
margin-left:0;
padding-left:0;
padding-right:30px;
text-align:left;
position:relative;
}
.block_mathquill_insert{
display:block;
position:absolute;
top:0;
bottom:0;
right:0;
left:0;
}
.theory_shuffle_box #sortable li {border:1px solid red;}
.to_middle{
vertical-align:middle;
}
.correct_width{
width:auto;
}
/****************************************************
* Ebook tabs
****************************************************/
.bookpage .ebooktabs.ui-tabs .ui-corner-all{
border-radius:8px 8px 0 0;
}
.bookpage .ebooktabs.ui-tabs{
padding:0;
background:inherit;
margin-left:1em;
margin-right:1em;
box-shadow:2px 2px 2px #ccc;
}
.bookpage .ebooktabs ul.ui-tabs-nav li a:hover{
color: inherit;
text-shadow:3px 3px 3px #777;
background-color:transparent;
}
.bookpage .ebooktabs.ui-tabs .ui-tabs-nav li a {
padding: 0.3em .8em;
}
.bookpage .ebooktabs.ui-tabs .ui-tabs-nav li.ui-state-active a:hover{
text-shadow:none;
cursor:default;
}
.bookpage .ebooktabs.ui-tabs .ui-tabs-nav li.ui-state-active {
box-shadow:2px -2px 2px #aaa;
}
/****************************************************
* Accordions
****************************************************/
div.ui-accordion a:hover {
background: none;
}
div.ui-accordion .ui-accordion-header a {
padding-top: 0.3em;
padding-bottom: 0.3em;
}
/****************************************************
* Images and graphs
****************************************************/
.ebookimage,
.functiongraph {
position: relative;
margin-left: auto;
margin-right: auto;
border: 1px solid #ccc;
border-radius: 5px;
padding: 1em;
text-align: center;
}
.ebookimage .imgcaption {
background-color: #ffa;
border: 1px solid #ccc;
padding: 0.5em;
margin-top: 2em;
text-align: left;
}
.ebookimage .imgcaption:before, .geocaption:before {font-weight: bold; padding-right: 1em;}
.ebookimage .imgcaption:lang(fi):before, .geocaption:lang(fi):before {content: "Kuva: ";}
.ebookimage .imgcaption:lang(en):before, .geocaption:lang(en):before {content: "Image: ";}
.ebookimage .imgcaption:lang(sv):before, .geocaption:lang(sv):before {content: "Bild: ";}
.ebookimage .imgcaption:lang(ee):before, .geocaption:lang(ee):before {content: "Pilt: ";}
.functiongraph .graphcaption {
background-color: #ffa;
border: 1px solid #ccc;
padding: 0.5em;
margin-top: 2em;
text-align: left;
}
.functiongraph .graphcaption:before {font-weight: bold; padding-right: 1em;}
.functiongraph .graphcaption:lang(fi):before {content: "Kuvaaja: ";}
.functiongraph .graphcaption:lang(en):before {content: "Graph: ";}
.functiongraph .graphcaption:lang(sv):before {content: "Graf: ";}
.functiongraph .graphcaption:lang(ee):before {content: "Graafik: ";}
.functiongraph .jsxgfunclist {
float: left;
background-color: white;
border: 1px solid #777;
border-radius: 5px;
box-shadow: 1px 1px 2px #777;
padding: 0.5em;
margin: 1em;
text-align: left;
}
.functiongraph .jsxgfunclist ul {
list-style: none;
padding: 0;
}
.graph_sliders {
width: 70%;
margin: 1em auto;
}
.graph_sliders .slider_data {
float: left;
margin-right: 2em;
}
.graph_sliders .graph_slider {
margin-left: 3em;
}
.graph_sliders .slider_element {
padding: 0.3em 0;
}
.graph_sliders .slider_element .slider_label {
font-weight: bold;
}
.graph_sliders .slider_element .slider_label:after {
content: " = ";
}
.graph_sliders .graph_slider {
margin: 0 4em;
}
/****************************************************
* Table layouts (.casetable)
****************************************************/
.casewrapper {display: inline-block; vertical-align: middle; border-left: none;}
.casewrapper .casebracket {position: static; vertical-align: middle; font-family: Symbola,"Times New Roman",Serif; display: inline-block;}
.casetable {display: inline-block; vertical-align: middle; padding-left: 0.4em;}
.casetable td {text-align: left;}
/****************************************************
* Table layouts (.value_table)
****************************************************/
.value_table {margin: 2em auto 2em 4em; border-collapse: collapse; background-color: #f3f3f3; border: 6px solid #f3f3f3;}
.value_table td:first-child,
.value_table th:first-child {
border-right: 1px solid black;
text-align: center;
}
.value_table td,
.value_table th {
min-width: 2em;
padding: 0.2em;
text-align: right;}
.value_table tr:first-child td,
.value_table tr:first-child th {
border-bottom: 1px solid black;
}
/****************************************************
* Table layouts (.column_table)
****************************************************/
.column_table {margin: 2em auto 2em 4em; border-collapse: collapse; background-color: #f3f3f3; border: 6px solid #f3f3f3;}
.column_table td,
.column_table th {
border-left: 1px solid black;
text-align: center;
min-width: 2em;
padding: 0.3em 0.7em;
}
.column_table td:first-child,
.column_table th:first-child {
border-left: none;
}
.column_table tr:first-child td,
.column_table tr:first-child th {
border-bottom: 1px solid black;
}
/****************************************************
* Table layouts (.no_borders)
****************************************************/
table.no_borders td {padding: 0.2em 0.5em;}
table.no_borders tr:first-child td {border-bottom: 1px solid black; font-weight: bold;}
table.no_borders {border-collapse: collapse; margin: 2em auto 2em 3em; background-color: #f7f7f7; border: 8px solid #f7f7f7;}
table.no_borders caption {border: 1px solid #999; padding: 0.3em 0.2em; font-size: 80%; text-align: left;}
table.no_borders caption:lang(fi):before {content: "Taulukko: "; font-weight: bold; display: block;}
table.no_borders caption:lang(en):before {content: "Table: "; font-weight: bold; display: block;}
table.no_borders caption:lang(sv):before {content: "Tabellen: "; font-weight: bold; display: block;}
table.no_borders caption:lang(ee):before {content: "Tabel: "; font-weight: bold; display: block;}
/****************************************************
* Table layouts (.theorytable)
****************************************************/
table.theorytable {margin: 1em auto; border: 2px solid #333; border-collapse:collapse}
table.theorytable td { padding: 0.3em 1em; border: 1px solid #999;}
/****************************************************
* Comment highlight
****************************************************/
.highlight {
position: relative;
}
.highlight .ebcomment {
position: absolute;
left: 0; top: 1em;
display: none;
}
.highlight:hover .ebcomment {
display: block;
border: 1px solid #888;
width: auto;
min-width: 10em;
box-shadow: 2px 2px 2px #555;
background-color: #ffa;
padding: 0.3em;
padding-top: 1.5em;
z-index: 5000;
}
.highlight:hover .ebcomment .removecomment {
position: absolute;
top: 0;
left: 0;
background-color: #a00;
color: white;
font-weight: bold;
text-align: center;
border: 1px solid white;
border-radius: 3px;
width: 1.2em;
box-shadow: 0 0 2px black;
}
.highlight:hover .ebcomment .removecomment:hover {
background-color: #f00;
cursor: pointer;
}
.highlight:hover .ebcomment .editcomment {
position: absolute;
top: 0;
right: 0;
background-color: #0a0;
color: white;
font-weight: bold;
text-align: center;
border: 1px solid white;
border-radius: 3px;
width: 1.2em;
box-shadow: 0 0 2px black;
}
.highlight:hover .ebcomment .editcomment:hover {
background-color: #0f0;
cursor: pointer;
}
.ebremoved {
text-decoration: line-through;
position: relative;
display: none;
}
.highlight:hover .ebremoved {
display: inline-block;
min-width: 0;
position: absolute;
top: -2em;
left: 0;
background-color: #faa;
color: black;
border: 1px solid red;
box-shadow: 2px 2px 2px #555;
width: auto;
white-space: nowrap;
z-index: 5000;
}
/************************************************************************************
* EmathbookNumberline
************************************************************************************/
.emathbooknumberline {height: 70px;}
tr.value_error input.addpointvalue {background-color: #faa;}
/************************************************************************************
* Otherassignment accordion
************************************************************************************/
.otherassignmentAccordion .question_text.plaintext,
.teacherAssignmentAccordion .question_text.plaintext
{border-bottom: 2px solid black;}
.otherassignmentAccordion ul.multichoiseChoises,
.teacherAssignmentAccordion ul.multichoiseChoises
{list-style: none;}
.otherassignmentAccordion ol ol,
.teacherAssignmentAccordion ol ol
{margin-top: 0.5em; margin-bottom: 0.5em;}
.otherassignmentAccordion ol ol > li,
.teacherAssignmentAccordion ol ol > li
{margin-top: 0.5em; margin-bottom: 0.5em;}
.otherassignmentAccordion ul.multichoiseChoises .multimark,
.teacherAssignmentAccordion ul.multichoiseChoises .multimark
{margin-right: 1.5em;}
.otherassignmentAccordion ul.multichoiseChoises .multimark .multicorrect,
.teacherAssignmentAccordion ul.multichoiseChoises .multimark .multicorrect
{padding-left: 0.5em; padding-right: 0.3em; color: green;}
.otherassignmentAccordion ul.multichoiseChoises .multimark .multiwrong,
.teacherAssignmentAccordion ul.multichoiseChoises .multimark .multiwrong
{padding-left: 0.5em; padding-right: 0.3em; color: red;}
.otherassignmentAccordion ul.multichoiseChoises.solved input,
.teacherAssignmentAccordion ul.multichoiseChoises.solved input
{visibility: hidden;}
.otherassignmentAccordion .shortanswer .solution.mathquill-editable,
.otherassignmentAccordion span.sdfill span.solution.mathquill-editable,
.teacherAssignmentAccordion .shortanswer .solution.mathquill-editable,
.teacherAssignmentAccordion span.sdfill span.solution.mathquill-editable
{background-color: white; border: 2px dotted #faa;}
.structuredderivation table.sdtable .mathquill-embedded-latex .mathquill-editable
{display: inline-block;}
.otherassignmentAccordion .shortanswer .solution,
.otherassignmentAccordion .sdfill .solution,
.teacherAssignmentAccordion .shortanswer .solution,
.teacherAssignmentAccordion .sdfill .solution
{background-color: white;}
.otherassignmentAccordion .shortanswer .solution > .mathquill-editable,
.otherassignmentAccordion .sdfill .solution > .mathquill-editable,
.teacherAssignmentAccordion .shortanswer .solution > .mathquill-editable,
.teacherAssignmentAccordion .sdfill .solution > .mathquill-editable
{background-color: white; min-width: 2em; display: inline-block;}
.otherassignmentAccordion .shortanswercorrect,
.teacherAssignmentAccordion .shortanswercorrect
{padding-left: 0.5em; color: green; font-size: 160%; position: absolute; margin-top: -0.2em;}
.otherassignmentAccordion ol > li > h1,
.teacherAssignmentAccordion ol > li > h1
{font-size: 100%; display: inline; border-bottom: none;}
.otherassignmentAccordion .structuredderivation a.button.command_qededit,
.otherassignmentAccordion .structuredderivation a.button.command_qededit,
.teacherAssignmentAccordion .structuredderivation a.button.command_qededit,
.teacherAssignmentAccordion .structuredderivation a.button.command_qededit
{display: none;}
div.solutionset div.structuredderivation a.button.command_qededit {display: inline-block;}
.otherassignmentAccordion .sdInOrder .qededitor,
.teacherAssignmentAccordion .sdInOrder .qededitor
{box-shadow: 0px 0px 20px green;}
.otherassignmentAccordion .tablefill table caption,
.teacherAssignmentAccordion .tablefill table caption
{min-width: 20em; text-align: left; margin-top: 0.5em;}
.otherassignmentAccordion .issolved .tablefill table,
.teacherAssignmentAccordion .issolved .tablefill table
{box-shadow: 0 0 20px green;}
.otherassignmentAccordion .issolved .qededitor,
.teacherAssignmentAccordion .issolved .qededitor
{box-shadow: 0px 0px 20px green;}
.sdbookassignmentlist .sdInOrder .qededitor:after,
.sdbookassignmentlist .issolved .qededitor:after,
.sdInOrder .sdbooksolsdshuffle .qededitor:after,
.issolved .sdbooksolsdshuffle .qededitor:after {
content: "\2713";
color: green;
position: absolute;
right: 50px;
bottom: 20px;
font-size: 700%;
text-shadow: 3px 3px 5px black;
}
/*
body[lang="fi"] .sdbookassignmentlist li.sdInOrder .qededitor:after,
body[lang="fi"] .sdbookassignmentlist li.issolved .qededitor:after {
content: "·/·";
}
body[lang="sv"] .sdbookassignmentlist li.sdInOrder .qededitor:after,
body[lang="sv"] .sdbookassignmentlist li.issolved .qededitor:after {
content: "R";
}
*/
.bookpage[curriculum="fi"] .sdbookassignmentlist li.sdInOrder .qededitor:after,
.bookpage[curriculum="fi"] .sdbookassignmentlist li.issolved .qededitor:after,
.bookpage[curriculum="fi"] .sdInOrder .sdbooksolsdshuffle .qededitor:after,
.bookpage[curriculum="fi"] .issolved .sdbooksolsdshuffle .qededitor:after {
content: "·/·";
}
.bookpage[curriculum='fi'] .sdbookassignmentlist .multimark .multicorrect:before {
content: '·/·';
font-weight: bold;
}
.bookpage[curriculum='fi'] .sdbookassignmentlist .multimark .multiwrong:before {
content: '\2713';
font-weight: bold;
}
.bookpage[curriculum="sv"] .sdbookassignmentlist li.sdInOrder .qededitor:after,
.bookpage[curriculum="sv"] .sdbookassignmentlist li.issolved .qededitor:after,
.bookpage[curriculum="sv"] .sdInOrder .sdbooksolsdshuffle .qededitor:after,
.bookpage[curriculum="sv"] .issolved .sdbooksolsdshuffle .qededitor:after {
content: "R";
}
.bookpage[curriculum='sv'] .sdbookassignmentlist .multimark .multicorrect:before {
content: 'R';
font-weight: bold;
}
.bookpage[curriculum='sv'] .sdbookassignmentlist .multimark .multiwrong:before {
content: '\2713';
font-weight: bold;
}
.bookpage[curriculum='fi'] .sdbookassignmentlist .multimark .multicorrect span,
.bookpage[curriculum='sv'] .sdbookassignmentlist .multimark .multicorrect span,
.bookpage[curriculum='fi'] .sdbookassignmentlist .multimark .multiwrong span,
.bookpage[curriculum='sv'] .sdbookassignmentlist .multimark .multiwrong span {
display: none;
}
/************************************************************************************
* Mathquill - extramotivation
************************************************************************************/
.qededitor:not(.qedediting) .extramotivation {
width: 1.4em;
height: 1.4em;
overflow: hidden;
display: inline-block;
vertical-align: middle;
color: white;
}
.qededitor .extramotivation:before {
content: "?";
display: inline-block;
width: 1.3em;
height: 1.3em;
line-height: 1.3em;
border-radius: 0.65em;
background-color: blue;
color: white;
font-weight: bold;
vertical-align: middle;
text-align: center;
cursor: pointer;
margin-right: 0.5em;
}
.qededitor .extramotivation.extrashow {
display: inline;
width: auto;
height: auto;
overflow: visible;
color: red;
}
/************************************************************************************
* SubTOC
************************************************************************************/
.subtocwrapper {
position: absolute;
bottom: 0;
left: 2em;
z-index: 8000;
}
.subtocwrapper .subtocinner {
position: absolute;
top: 0;
left: 0;
min-width: 15em;
font-size: 110%;
background-color: white;
border: 1px solid #999;
border-radius: 4px;
white-space: nowrap;
padding: 0.3em;
box-shadow: 6px 6px 6px #999;
background: rgb(249,249,249); /* Old browsers */
background: -moz-linear-gradient(top, rgba(249,249,249,1) 0%, rgba(234,234,234,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(249,249,249,1)), color-stop(100%,rgba(234,234,234,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(249,249,249,1) 0%,rgba(234,234,234,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(249,249,249,1) 0%,rgba(234,234,234,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(249,249,249,1) 0%,rgba(234,234,234,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(249,249,249,1) 0%,rgba(234,234,234,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f9f9f9', endColorstr='#eaeaea',GradientType=0 ); /* IE6-9 */
}
.subtocwrapper ul {
margin: 0;
padding: 0;
padding-left: 0.7em;
}
.subtocwrapper ul.subtoc {
list-style: none;
}
.subtocwrapper ul.subtoc ul.subtoc {
margin-bottom: 0.4em;
}
.subtocwrapper ul.subtoc li.subtocitem.iscurrentpage li.subtocitem {
font-weight: normal;
}
.subtocwrapper ul.subtoc li.subtocitem.iscurrentpage ul {
background-color: white;
}
.subtocwrapper ul.subtoc li.subtocitem.iscurrentpage > a {
color: black;
text-decoration: underline;
}
.subtocwrapper ul.subtoc li.subtocitem.iscurrentpage > a:hover {
background-color: transparent;
}
.subtocwrapper ul.subtoc li.subtocitem.iscurrentpage {
font-weight: bold;
background-color: #ccf;
}
/************************************************************************************
* PageSelect
************************************************************************************/
#pageOneWrapper .pageselect {
height: 40px;
display: inline-block;
vertical-align: bottom;
float: right;
margin-right: 10px;
margin-left: -50px;
width: 67px;
background: transparent url([[Book_two_pages.png]]) left top no-repeat;
cursor: pointer;
}
#pageTwoWrapper .pageselect {
height: 40px;
display: inline-block;
vertical-align: bottom;
float: right;
margin-right: 10px;
margin-left: -50px;
width: 36px;
background: transparent url([[Book_one_page.png]]) left top no-repeat;
cursor: pointer;
}
#contentWrapper[pageopen] #pageOneWrapper .pageselect {
display: none;
width: 36px;
background: transparent url([[Book_one_page.png]]) left top no-repeat;
}
/************************************************************************************
* Bookshelf
************************************************************************************/
ul.bookshelf {
list-style: none;
padding: 0;
max-height: 20em;
overflow: auto;
}
ul.bookshelf li.bookshelfitem {
/* display: inline-block; */
/* max-width: 10em; */
/* text-align: center; */
text-align: left;
vertical-align: top;
margin: 0.5em;
padding: 0;
border: 1px solid #999;
border-radius: 5px;
clear: both;
position: relative;
}
ul.bookshelf li.bookshelfitem a {
display: block;
margin: 0;
padding: 0;
/* height: 14em; */
}
ul.bookshelf li.bookshelfitem a:hover {
background-color: transparent;
color: blue;
}
ul.bookshelf li.bookshelfitem:hover {
background-color: white;
border: 1px solid black;
border-radius: 5px;
box-shadow: 0 0 8px #ffa;
}
ul.bookshelf li.bookshelfitem.currentbook {
border: 1px solid red;
background-color: #ffa;
}
ul.bookshelf li.bookshelfitem a:after {
content: " ";
display: block;
clear: both;
}
ul.bookshelf li.bookshelfitem a img {
float: left;
width: 50px;
margin: 0.5em;
}
ul.bookshelf li.bookshelfitem a p {
margin: 0;
padding: 0.5em;
}
ul.bookshelf li.bookshelfitem ul.bookitemlangs {
list-style: none;
margin:0;
padding: 0;
position: absolute;
bottom: 0;
right: 0;
}
ul.bookshelf li.bookshelfitem ul.bookitemlangs {
list-style: none;
margin:0;
padding: 0;
vertical-align: bottom;
text-align: right;
}
ul.bookshelf li.bookshelfitem ul.bookitemlangs li.booklang {
display: inline-block;
padding: 0;
border: 1px solid #999;
background-color: black;
color: white;
margin: 0;
text-align: center;
}
ul.bookshelf li.bookshelfitem ul.bookitemlangs li.booklang span {
color: white;
font-weight: bold;
display: inline-block;
min-width: 2em;
padding: 0.2em;
margin: 0;
}
ul.bookitemlangs li.booklang.currentlang span {
background-color: red;
}
ul.bookitemlangs li.booklang.currentlang span:hover {
background-color: #f55;
}
ul.bookshelf li.bookshelfitem ul.bookitemlangs li.booklang span:hover {
background-color: #faa;
color: black;
}
/************************************************************************************
* Bookshelf - apps
************************************************************************************/
.ebookshelf_apps ul.applist li img {
height: 40px;
widht: auto;
}
.ebookshelf_apps ul.applist li.applistitem {
display: inline-block;
padding: 2px;
}
.ebookshelf_apps ul.applist li.applistitem a {
display: block;
}
.ebookshelf_apps ul.applist li.applistitem {
display: inline-block;
border: 1px solid black;
border-radius: 3px;
background-color: white;
}
.ebookshelf_apps ul.applist {
list-style: none;
margin: 0;
padding: 0.4em 1em;
background-color: #ff8000;
border-radius: 6px 6px 0 0;
}
/************************************************************************************
* Ebookapps
************************************************************************************/
.ebookappbox {
margin: 2em;
box-shadow: 8px 8px 12px #555;
display: inline-block;
}
.chatwindow {
display: inline-box;
}
.chatwindow h1 {
margin: 0 0 0.3em 0;
border: none;
font-size: 150%;
}
.chatwindow input {
width: 298px;
border: 1px solid black;
}
/************************************************************************************
* Extrabox
************************************************************************************/
.ebwrapper {
position: relative;
}
.extraboxicon {
display: inline-block;
height: 50px;
width: 50px;
position: relative;
float: right;
z-index: 10;
clear: right;
}
.extraboxicon:hover {
cursor: pointer;
}
.extraboxicon.extrabox_hint {
margin-right: 0.5em;
margin-top: 3em;
width: 26px;
height: 30px;
background: transparent url([[icon_hint.png]]) left top no-repeat;
}
.extraboxicon.extrabox_extra {
margin-right: 0.5em;
margin-bottom: 1.5em;
margin-top: 0;
width: 26px;
height: 25px;
background: transparent url([[icon_extra.png]]) left top no-repeat;
}
.extraboxicon.extrabox_modelsolution {
margin-right: 40px;
margin-top: 0.5em;
width: 30px;
height: 20px;
background-color: red;
display: inline-block;
background: transparent url([[icon_puzzle.png]]) left top no-repeat;
}
.extraboxwrapper {
position: fixed;
top: 10em;
border: 1px solid #aaa;
/* border-top: 25px solid #aaa; */
border-radius: 8px;
background-color: white;
z-index: 99;
padding-bottom: 10px;
box-shadow: 10px 10px 25px black;
cursor: default;
}
.extraboxwrapper.bigbox .extraboxcontent {
width: auto;
}
.extraboxwrapper.bigbox .ebcontent {
display: block;
width: auto;
}
#pageOneWrapper .extraboxwrapper {
left: 70px;
}
#pageTwoWrapper .extraboxwrapper {
left: 70px;
}
.extraboxcontent {
background-color: white;
min-width: 500px;
width: 25em;
border-radius: 8px 8px 0 0;
}
.extraboxwrapper .extraboxclose {
position: absolute;
top: 2px;
right: 2px;
width: 16px;
height: 16px;
color: white;
font-weight: bold;
text-align: center;
vertical-align: middle;
border-radius: 8px;
background-color: red;
border: 1px solid black;
cursor: pointer;
}
.extraboxwrapper .extraboxcontent h1.extratitle {
background-color: #ffa;
border-bottom: none;
margin: 0;
font-size: 120%;
min-height: 1.5em;
border-radius: 8px 8px 0 0;
}
.extraboxwrapper .extraboxcontent .ebcontent {
margin: 1em;
display: block;
}
.pageWrapper.hasbigbox .pageNavi {
display: none;
}
.pageWrapper.hasbigbox .bookpage {
display: none;
}
#pageOneWrapper.hasbigbox .extraboxwrapper.bigbox,
#pageTwoWrapper.hasbigbox .extraboxwrapper.bigbox {
position: relative;
top: 0;
left: 0;
right: 0;
margin: 1em 2em 2em 1em;
padding: 0;
padding-bottom: 6em;
width: auto;
}
.pageWrapper.hasbigbox .extraboxwrapper.bigbox .extraboxcontent {
width: auto;
min-width: none;
max-width: none;
max-height: none;
}
.pageWrapper.hasbigbox .extraboxwrapper.bigbox .ebcontent {
height: auto;
overflow: auto;
width: auto;
}
.hasbigbox .extraboxwrapper.bigbox {
border: none;
box-shadow: none;
}
.hasbigbox .extraboxwrapper.bigbox .extraboxcontent {
border: 1px solid black;
box-shadow: 5px 5px 5px rgba(0,0,0,0.5);
border-radius: 8px;
margin: 2em 0;
}
.extraboxcontent a.button.command_qededit {
display: none;
}
/************************************************************************************
* backstage
************************************************************************************/
a.backstageTab {
display: none;
}
a.backstageTab[task="ebookTheme"] {
display: inline;
}
a.backstageTab[task="ebookSettings"] {
display: inline;
}
body.adminmode a.backstageTab {
display: inline;
}
#ebsettingsdialog .settingsPanel {
background-color: transparent;
border: none;
}
/************************************************************************************
* Page comments
************************************************************************************/
.pagecommentblock {
border: 1px solid #999;
border-radius: 5px;
max-width: 40em;
box-shadow: 4px 4px 5px #777;
margin: 1em 0.3em;
}
.pagecommentblock br {
display: block;
margin: 0.3em 0;
}
.pagecommentblock .pagecommenthead {
border-radius:6px 6px 0 0;
background-color: #ffa;
color: black;
padding: 0.3em 0.5em;
}
.pagecommentblock.content .pagecommenthead {
background-color: #afa;
}
.pagecommentblock.system .pagecommenthead {
background-color: #aff;
}
.pagecommentblock.layout .pagecommenthead {
background-color: #faf;
}
.pagecommentblock .pagecommenthead .pagecommentauthor {
font-weight: bold;
display: block;
padding: 0;
}
.pagecommentblock .pagecommenthead .pagecommenttype {
font-style: italic;
display: block;
float: right;
padding: 0.1em;
text-shadow: 1px 1px 0.5px white;
}
.pagecommentblock .pagecommenthead .pagecommentdate {
color: #444;
display: block;
padding: 0;
}
.pagecommentblock .pagecommentbody {
background-color: white;
color: black;
padding: 0.3em 0.5em;
margin: 0.5em 0 10px 0;
}
.pagecommentblock .pagecommentbody h1 {
font-size: 150%;
margin: 0 0 0.5em 0;
}
#pageOne .ebooktitle a.commentsnotify {
display: inline-block;
float: right;
}
#pageOne .ebooktitle a.commentsnotify:hover {
background: transparent;
}
#pageOne .ebooktitle a.commentsnotify img {
width: 50px;
height: auto;
}
#pageOne h1.ebooktitle a.commentsnotify:hover img {
width: 55px;
}
#AllcommentsWrapper {
margin: 1em;
border: 3px solid red;
border-radius: 1em;
padding: 2em;
background-color: white;
}
#coursecommentnavi {
margin-top: -2em;
}
#coursecommentnavi ul#commentList {
background-color: #f0f0f0;
height: 15em;
position: relative;
border: 1px solid black;
border-top: 2px solid #777;
border-left: 2px solid #777;
border-right: 2px solid #aaa;
border-bottom: 2px solid #aaa;
overflow: auto;
padding: 0;
}
#coursecommentnavi ul#commentList li.selectComment {
padding: 0.2em 0.5em;
cursor: pointer;
}
#coursecommentnavi ul#commentList li.selectComment.shownComment {
border: 1px solid #a00;
box-shadow: inset 0 5px 8px rgba(150,0,0,0.5), inset 0 -5px 8px rgba(150,0,0,0.5);
background-color: #fee;
}
#coursecommentnavi ul#commentList li.selectComment:nth-child(odd) {
background-color: #fff6d5;
}
#coursecommentnavi ul#commentList li.selectComment:nth-child(even) {
background-color: #fea;
}
#coursecommentnavi ul#commentList li.selectComment .commentSent {
display: inline;
font-size: 70%;
}
#coursecommentnavi ul#commentList li.selectComment .commentSender {
font-style: italic;
display: block;
}
#coursecommentnavi ul#commentList li.selectComment .commentToText {
display: block;
font-weight: bold;
}
/*************************
Ebooktitles
**************************/
.bookpage[types~="front"] h1.ebooktitle {font-size: 300%; text-align: center; border-bottom: 8px double black;}
.bookpage[types~="chapter"] h1.ebooktitle {font-size: 250%; border-bottom: 4px double black; margin-top: 0.2em;}
.bookpage[types~="section"] h1.ebooktitle {font-size: 200%; margin-top: 0.5em;}
.bookpage h1.ebooktitle {font-size: 150%; margin-top: 1em;}
.bookpage[types~="noheader"] h1.ebooktitle {display: none;}
/*************************
Geoeditor
**************************/
.geoeditorleft {
float: left;
}
.geoeditorright {
float: right;
}
.geoeditorcenter {
margin-left: auto;
margin-right: auto;
}
/*************************
Studentview
**************************/
body.studentview .pageWrapper {
border: 4px solid red;
}
body.studentview button.publishbutton,
body.studentview h3 button.publishbutton {
display: none;
}
/*************************
TOC-edit
**************************/
#authordialog_tocedit table.translatetable {
margin-top: 1em;
border-collapse: collapse;
width: 100%;
}
#authordialog_tocedit table.translatetable th {
background-color: black;
color: white;
border-left: 1px solid black;
border-right: 1px solid black;
}
#authordialog_tocedit table.translatetable td {
padding: 0.1em 0.5em;
border-left: 1px solid black;
border-right: 1px solid black;
}
#authordialog_tocedit table.translatetable td:nth-child(4) {
padding: 0.1em 0;
}
#authordialog_tocedit table.translatetable td input[type="text"] {
display: block;
margin: 0;
width: 100%;
box-sizing: border-box;
-webkit-box-sizing:border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
}
#authordialog_tocedit table.translatetable tr:nth-child(2n) {
background-color: #ffa;
}
#authordialog_tocedit table.translatetable tr:nth-child(2n+1) {
background-color: #ffd;
}
#authordialog_tocedit .booknamearea input.nametext {
width: 99%;
}
.ui-dialog h2 {color: black; border-bottom: 1px solid black;}
/*************************
Youtube
**************************/
.ytvideo {text-align: center;}
.ytvideo iframe {display: inline-block; width: 560px; height: 315px;}
#contentWrapper[pageopen] .ytvideo iframe {width: 400px; height: 310px;}
/**********************************************************
* Linebreaks
**********************************************************/
span.eblinebreak {
display: block;
height: 0;
margin: 0;
}
span.ebparbreak {
display: block;
height: 0;
margin: 0;
}
/**********************************************************
* Askusername
**********************************************************/
#askusername p.onelinenowrap {
white-space: nowrap;
}
#askusername input#getteachername {
width: 4em;
}
/**********************************************************
* SD step by step
**********************************************************/
.stepBystepButtonset button.ui-button.ui-widget {padding: 0 2.5em; height: 1.5em;}
/**********************************************************
* Updateinfo
**********************************************************/
#updateinfo a,
#updateinformation a {
color: blue;
text-decoration: underline;
}
#updateinfo a:hover,
#updateinformation a:hover {
background-color: transparent;
color: #55f;
text-decoration: underline;
}
#updateinformation.ui-widget-content {
background-color: white;
margin: 0.5em;
border: 1px solid #999;
box-shadow: inset 0 0 15px rgba(0,0,0,0.3);
}
#updateinformation table {
border-collapse: collapse;
margin: 0.5em 0.5em 0.5em 2em;
}
.infohead {
font-size: 150%;
font-weight: bold;
border-bottom: 2px solid black;
display: block;
padding: 1em 0 0 0;
margin-bottom: 0.5em;
}
/**********************************************************
* Teacher addtools
**********************************************************/
.teacherElementsetwrapper span.teacherTitle.mathquill-textbox {
display: block;
background-color: rgba(255,255,255,0.6);
}
.teacherElementsetwrapper span.sdbooksoltext span.mathquill-textbox,
.modelsolutionsetwrapper span.sdbooksoltext span.mathquill-textbox {
display: block;
background-color: rgba(255,255,255,0.6);
}
.teacherElementsetwrapper span.sdbooksolwikitext textarea.wikitextEdit,
.modelsolutionsetwrapper span.sdbooksolwikitext textarea.wikitextEdit {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 8em;
padding: 0.2em;
}
.teacherElementsetwrapper .teacherAddtoolbar,
.modelsolutionsetwrapper .solutiontoolbar {
text-align: center;
}
.notrashcan .removesolelem{
display:none;
}
.noAllanswers{border:3px dotted red;}
/**********************************************************
* Mathquill buttonpanel
**********************************************************/
#mathquillpanel.mqpanel_wrapper {z-index: 1005;}
.mqpanel_wrapper[orientation="vertical"] {margin-bottom: 40px; margin-top: 40px;}
.mqpanel_wrapper[orientation="horizontal"] {margin-left: 40px; margin-right: 40px;}
.mqpanel_wrapper {display: none;}
body.showmqpanel .mqpanel_wrapper {display: block;}
body.showmqpanel .mqpanelvisible,
.mqpanelnonvisible
{display: none;}
body.showmqpanel .mqpanelnonvisible {display: inline;}
/**********************************************************
* Assignment answer
**********************************************************/
.teacherassignmentSolution.hidden .assignmentSolution,
.teacherassignmentSolution.hidden .hideTeacherAssignmentSolution
{display: none;}
.teacherassignmentSolution.hidden .answerString {text-transform: none;}
.teacherassignmentSolution .answerString {text-transform: lowercase;}
.assignmentSolution {margin: 1em; padding: 0.3em 1em; background-color: rgba(255,255,255,0.5); border: 1px solid #aaa; border-radius: 4px;}
.teacherassignmentSolution {margin: 1em 0;}
.teacherassignmentSolution button {margin-left: 1em;}
/**********************************************************
* Close book
**********************************************************/
#bookclosedwindow {position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 10000; background-color: #deebf5;}
#bookclosedwindow #bookclosecontent {width: 800px; margin: 50px auto 0 auto;}
#bookclosedwindow h1 {text-align: center; color: black; font-size: 400%; border: none;}
#bookclosedwindow a {display: block; margin-left: auto; margin-right: auto; width: 12em; font-size: 200%; border: 3px solid #a00; border-radius: 1em; padding: 1em; background-color: white; color: #a00; text-align: center;
box-shadow: 0 0 5px rgba(0,0,0,0.5);
text-shadow: 0 0 6px white;
background: rgb(184,225,252); /* Old browsers */
background: -moz-linear-gradient(top, rgba(184,225,252,1) 0%, rgba(169,210,243,1) 10%, rgba(144,186,228,1) 25%, rgba(144,188,234,1) 37%, rgba(144,191,240,1) 50%, rgba(107,168,229,1) 51%, rgba(162,218,245,1) 83%, rgba(189,243,253,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(184,225,252,1)), color-stop(10%,rgba(169,210,243,1)), color-stop(25%,rgba(144,186,228,1)), color-stop(37%,rgba(144,188,234,1)), color-stop(50%,rgba(144,191,240,1)), color-stop(51%,rgba(107,168,229,1)), color-stop(83%,rgba(162,218,245,1)), color-stop(100%,rgba(189,243,253,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(184,225,252,1) 0%,rgba(169,210,243,1) 10%,rgba(144,186,228,1) 25%,rgba(144,188,234,1) 37%,rgba(144,191,240,1) 50%,rgba(107,168,229,1) 51%,rgba(162,218,245,1) 83%,rgba(189,243,253,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(184,225,252,1) 0%,rgba(169,210,243,1) 10%,rgba(144,186,228,1) 25%,rgba(144,188,234,1) 37%,rgba(144,191,240,1) 50%,rgba(107,168,229,1) 51%,rgba(162,218,245,1) 83%,rgba(189,243,253,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(184,225,252,1) 0%,rgba(169,210,243,1) 10%,rgba(144,186,228,1) 25%,rgba(144,188,234,1) 37%,rgba(144,191,240,1) 50%,rgba(107,168,229,1) 51%,rgba(162,218,245,1) 83%,rgba(189,243,253,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(184,225,252,1) 0%,rgba(169,210,243,1) 10%,rgba(144,186,228,1) 25%,rgba(144,188,234,1) 37%,rgba(144,191,240,1) 50%,rgba(107,168,229,1) 51%,rgba(162,218,245,1) 83%,rgba(189,243,253,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b8e1fc', endColorstr='#bdf3fd',GradientType=0 ); /* IE6-9 */
}
/**********************************************************
* Print preview
**********************************************************/
body.emathprintpreview {background: white;}
body.emathprintpreview > div.printhide {display: none!important;}
#emathprint .generalfeedback, #emathprint .manualcheck {display: none;}
#emathprint.printmarkingsshow .generalfeedback {display: block;}
#emathprint.printmarkingsshow .manualcheck {display: inline-block;}
#emathprint.printmarkingsshow .manualcheck .checkcomment {display: inline-block;}
#emathprint {padding: 2em; max-width: 70em; font-size: 120%;}
@media print {#emathprint {padding: 0; max-width: 70em; font-size: 100%;}}
@media print {#emathprint .printtools {display: none;}}
#emathprint h2 {color: black; border-bottom: none; font-family: serif;}
#emathprint h1 {color: black; border-bottom: 2px solid black; font-family: serif; font-size: 200%;}
.emathprintpreview .printassignment {margin: 2em 0; border: 1px solid #999; padding: 1em; border-radius: 4px; box-shadow: inset 0 0 0.6em rgba(0,0,0,0.3);}
.emathprintpreview .solutionset {margin: 2em 0; border: 1px solid #999; padding: 1em 0.5em; border-radius: 4px;}
body.emathprintpreview #emathprint {position: relative;}
body.emathprintpreview #emathprint .printtools {position: fixed; top: 20px; border: 2px solid #555; border-radius: 1em; padding: 1em; background-color: rgba(0,0,0,0.5); margin-left: 40%; z-index: 400;}
body.emathprintpreview #emathprint .printtools a {box-shadow: 0 0 6px white;}
/**********************************************************
* Hide things
**********************************************************/
a.ui-dialog-titlebar-close {display: none;}
/**********************************************************
* Pagecopytools
**********************************************************/
ul.pagecopytools {display: none;}
#contentWrapper.elementselectmode .bookpage [tiddler] ul.pagecopytools {position: relative; list-style: none; padding: 0; margin: 0; z-index: 2;}
#contentWrapper.elementselectmode .bookpage [tiddler] ul.pagecopytools li {display: inline-block; padding: 0; margin: 0;}
#contentWrapper.elementselectmode .bookpage > [tiddler] > ul.pagecopytools {margin: -28px 0 0 -20px; float: left;}
#contentWrapper.elementselectmode .bookpage > [tiddler] > [tiddler] > ul.pagecopytools {margin: -15px 0 -10px 0; height: 20px; float: right; display: none;}
/**********************************************************
* Homeassignments / Bookmarks
**********************************************************/
/*Opettajan "title" kotitehtäville esim. Tee ainakin punaiset tai jotain...*/
#hometitleinput {
position: fixed;
top: 30px;
right: 15px;
min-width: 30px;
border: 1px solid rgb(102, 102, 102);
padding: 2px;
border-radius: 4px 4px 4px 4px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
background: linear-gradient(to bottom, rgb(238, 238, 238) 0%, rgb(204, 204, 204) 100%) repeat scroll 0% 0% transparent;
}
#hometitleinput h4 {
color: black;
}
#hometitleinput .hometitleinput {
display: block;
background-color: white;
}
/*Sulje-nappula span jossa lukee sulje */
#closeBookmarks {
position: fixed;
top: 50px;
right: 50px;
cursor: pointer;
border: 1px solid rgb(102, 102, 102);
padding: 2px 10px;
border-radius: 15px 15px 15px 15px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
text-shadow: 2px 2px 2px gray;
color:white;
background: linear-gradient(to bottom, rgba(229,221,220,1) 0%,rgba(247,116,93,1) 50%,rgba(229,221,220,1) 100%);
}
/*Kotitehtävälistan alkiot */
.bookmarktimestamp{
font-family: serif;
list-style: none;
font-size:120%;
font-weight: bold;
font-style: italic;
text-decoration: underline;
color: black;
padding:0.3em 0;
}
.homeassignmentsitem{
padding:0.1em 0;
margin:0 3em;
cursor: pointer;
}
.homeassignmentsitem:hover {
background-color: rgba(255,255,255,0.5);
}
/*editointikalut piiloon kotitehtäviä laitettaessa*/
.addhomeassignmentMarks .teachertoolbar {
display:none;
}
/* Jotenkin merkattava valitun kerran tehtävät jos useita olemassa*/
h3.homeassignment.highlightHomeassignment{
border:1px solid red;
box-shadow: inset 0 0 5px red, 0 0 5px red;
}
/*}}}*/
/*{{{*/
@media print {
#displayArea {
border-image: none;
-moz-border-image: none;
-webkit-border-image: none;
-o-border-image: none;
-ms-border-image: none;
position: static;
overflow: auto;
margin: 0;
padding: 0;
background: transparent;
}
#actionButtons,
.ebooknavibar,
#mainMenu,
.solutionControl,
.qededitor .qededitorbuttons a.button.command_qededit,
#mathbuttonwrapper,
.bookpage .ebooktoc.coursebook
{display: none;}
.ui-accordion-content,
td.subderivation .sdsubderivation
{display: block!important;}
.qededitor,
.ui-accordion-content,
.ebookbox
{page-break-inside:avoid;}
.contentPagebrake {
display: block;
page-break-after: always;
}
#AllcommentsWrapper {border: none; padding: 0;}
#ShowAllPageComments {margin: 0; padding: 0;}
.pagecommentblock {max-width: none; width: auto;}
}
/*}}}*/
/*{{{*/
body[ebooktheme="academic"] .ebookbox .sdbookexample h1,
body[ebooktheme="academic"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
}
body[ebooktheme="academic"] .ebookbox .sdbookexample,
body[ebooktheme="academic"] .ebookbox .sdbooktheory {
background-color: transparent;
border: none;
box-shadow: none;
margin-left: 0;
}
body[ebooktheme="academic"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="academic"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="academic"] .ebookimage .imgcaption,
body[ebooktheme="academic"] .functiongraph .graphcaption {
border: 1px solid #999;
background-color: white;
}
/*}}}*/
/*{{{*/
body[ebooktheme="pink"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="pink"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;}
body[ebooktheme="pink"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="pink"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="pink"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="pink"] #contentWrapper .header {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="pink"] .bookpage h1.ebooktitle {color: #a00; border-bottom: 2px solid #a00;}
body[ebooktheme="pink"] .ebookbox .sdbookexample h1,
body[ebooktheme="pink"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="pink"] .ebookbox .sdbookexample,
body[ebooktheme="pink"] .ebookbox .sdbooktheory {
background-color: transparent;
border: none;
box-shadow: none;
margin-left: 0;
}
body[ebooktheme="pink"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="pink"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="pink"] .ebookimage .imgcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="pink"] .functiongraph .graphcaption {
border: 1px solid #900;
background-color: white;
}
/*}}}*/
/*{{{*/
/* Ebook theme - red */
body.ebookthemeRed {
background: #e9afaf url([[tausta-red.jpg]]) left top repeat-x;
}
body.ebookthemeRed .header {
background-color: [[ColorPaletteOwn::HeaderBgRed]];
}
body.ebookthemeRed #mainMenu {
background-color: [[ColorPaletteOwn::HeaderBgRed]];
}
body.ebookthemeRed #mainMenu:hover {
background-color: white;
}
body.ebookthemeRed #mainMenu:hover h1 {
background-color: [[ColorPaletteOwn::HeaderBgRed]];
}
/*}}}*/
/*{{{*/
/* Add Here links to custom Ebook-themes */
[[StyleSheetEbookTheme_red]]
[[StyleSheetEbookTheme_gradient]]
[[StyleSheetEbookTheme_academic]]
[[StyleSheetEbookTheme_pink]]
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}
hr {height:1px;}
a {text-decoration:none;}
dt {font-weight:bold;}
ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}
.txtOptionInput {width:11em;}
#contentWrapper .chkOptionInput {border:0;}
.externalLink {text-decoration:underline;}
.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}
.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
#mainMenu .tiddlyLinkExisting,
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:1.5em 0 1em 3em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:1.5em 0 1em 3em; left:0px; top:0px;}
.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
#mainMenu ul {margin: 0; padding: 0;}
#mainMenu ul li {margin: 0; padding: 0;}
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}
#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}
.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}
.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}
#contentWrapper {display:block;}
#splashScreen {display:none;}
#displayArea {margin:1em auto 0 3em; width: 60em;}
.toolbar {text-align:right; font-size:.9em;}
.tiddler {padding:1em 1em 0;}
.missing .viewer,.missing .title {font-style:italic;}
.title {font-size:1.6em; font-weight:bold;}
.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}
.tiddler .button {padding:0.2em 0.4em;}
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}
.footer {font-size:.9em;}
.footer li {display:inline;}
.annotation {padding:0.5em; margin:0.5em;}
* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}
.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}
.fieldsetFix {border:0; padding:0; margin:1px 0px;}
.sparkline {line-height:1em;}
.sparktick {outline:0;}
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}
* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/*{{{*/
/*************
* Tyylejä sivun rakenteelle
* Petri Salmela
* 19.2.2011
*************/
.floatRight {
float: right;
margin: 0.5em 0 0.5em 0.5em;
}
textarea[edit="text"] {
font-family: monospace;
}
.tiddler {
padding-bottom: 1em;
margin-bottom: 1em;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
}
.toolbar {
padding-top: 22px;
}
.toolbar .button {
padding-top: 22px;
min-width: 24px;
}
.button.command_closeTiddler {
background: transparent url('[[button-close.png.base64]]') center 2px no-repeat;
}
.button.command_editTiddler {
background: transparent url('[[button-edit.png.base64]]') center 2px no-repeat;
}
.button.command_saveTiddler {
background: transparent url('[[button-ok.png.base64]]') center 2px no-repeat;
}
.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background-color:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background-color:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
/*}}}*/
/*{{{*/
/**********************************
* QedEditor
**********************************/
.qededitor {}
.qededitor {
position: relative;
}
/**********************************
* Structured derivation -block
**********************************/
.structuredderivation {
position: relative;
margin: 0;
padding: 0.3em;
}
/**********************************
* Look of structured derivation
**********************************/
.structuredderivation {
font-size: 100%;
min-height: 15em;
border-width: 8px 1px 8px 1px;
-moz-border-image: url(../images/paperrip.png) 8 1 8 1 repeat repeat;
-webkit-border-image: url(../images/paperrip.png) 8 1 8 1 repeat repeat;
-o-border-image: url(../images/paperrip.png) 8 1 8 1 repeat repeat;
border-image: url(../images/paperrip.png) 8 1 8 1 fill repeat repeat;
border-style: solid;
}
.structuredderivation table.sdtable {
border-collapse: collapse;
border: none;
margin: 0;
padding: 0.3em 0;
background: transparent none;
width: 100%;
}
.structuredderivation table.sdtable td {
padding: 0;
margin: 0;
vertical-align: baseline;
}
.structuredderivation table.sdtable table.sdtable {
border-collapse: collapse;
background: none;
border-width: 0;
border-image: none;
-moz-border-image: none;
-webkit-border-image: none;
-o-border-image: none;
border: none;
}
.structuredderivation .sdtable td:first-child {
min-width: 2em;
max-width: 6em;
width: 4em;
text-align: center;
padding: 0;
overflow: visible;
}
.structuredderivation .sdtable td:first-child+td {
padding: 0.3em 0;
}
.structuredderivation .sdtable tr,
.structuredderivation .sdtable td {
border: none;
}
.structuredderivation .qededitorbuttons {
display: block;
margin:0;
}
.structuredderivation .qededitorbuttons a.button {
display: inline-block;
vertical-align: bottom;
width: 1em;
height: 1em;
border-top: 2px solid #faa;
border-left: 2px solid #faa;
border-right: 2px solid #faa;
border-radius: 8px 8px 0 0;
-webkit-border-radius: 8px 8px 0 0;
}
.structuredderivation .qededitorbuttons a.button:hover {
background-color: #faa;
text-decoration: none;
}
.structuredderivation .qededitorbuttons a.button span {
width: 0.9em;
height: 0.9em;
}
.structuredderivation .button.command_qededit {
background: transparent url('../images/button-edit.png') center center no-repeat;
}
.structuredderivation .button.command_qedundo,
.structuredderivation .button.command_qedredo {
font-weight: bold;
font-size: 180%;
color: #ddd;
text-align: center;
}
.structuredderivation .button.command_qedundo.active,
.structuredderivation .button.command_qedredo.active {
color: black;
}
.structuredderivation a.button.command_qedclose.command_editorclose {
display: inline-block;
background: transparent url('../images/button-close.png') center center no-repeat;
}
.structuredderivation table.sdtable .mathquill-editable {
border: none;
margin: 0 0.3em 0 0.3em;
display: block;
}
.structuredderivation table.sdtable .relation .mathquill-editable {
border: none;
margin: 0 0.3em 0 0;
}
.structuredderivation table.sdtable .mathquill-editable:hover {
background-color: rgba(190,240,255,0.2);
}
.structuredderivation table.sdtable .mathquill-textbox:hover {
background-color: rgba(255,170,170,0.2);
}
.structuredderivation table.sdtable td.motivation span.motivationstring:before,
.structuredderivation table.sdtable td.obsmotivation span.motivationstring:before,
.structuredderivation table.sdtable td.derivmotivation span.motivationstring:before {
content: "{ ";
}
.structuredderivation table.sdtable td.motivation span.motivationstring:after,
.structuredderivation table.sdtable td.obsmotivation span.motivationstring:after,
.structuredderivation table.sdtable td.derivmotivation span.motivationstring:after {
content: " }";
}
/*********************************
* Editing look
*********************************/
div.structuredderivation.sdediting span.motivationstring span.mathquill-textbox {
display: inline-block;
}
div.structuredderivation.sdediting table.sdtable {
border: 4px solid #faa;
}
div.structuredderivation.sdediting table.sdtable table.sdtable {
border: none;
}
.structuredderivation.sdediting table.sdtable td.motivation span.motivationstring:before,
.structuredderivation.sdediting table.sdtable td.obsmotivation span.motivationstring:before,
.structuredderivation.sdediting table.sdtable td.derivmotivation span.motivationstring:before {
content: none;
}
.structuredderivation.sdediting table.sdtable td.motivation span.motivationstring:after,
.structuredderivation.sdediting table.sdtable td.obsmotivation span.motivationstring:after,
.structuredderivation.sdediting table.sdtable td.derivmotivation span.motivationstring:after {
content: none;
}
.structuredderivation.sdediting table.sdtable td.motivation span.motivationstring span.mathquill-textbox:before,
.structuredderivation.sdediting table.sdtable td.obsmotivation span.motivationstring span.mathquill-textbox:before,
.structuredderivation.sdediting table.sdtable td.derivmotivation span.motivationstring span.mathquill-textbox:before {
content: "{ ";
}
.structuredderivation.sdediting table.sdtable td.motivation span.motivationstring span.mathquill-textbox:after,
.structuredderivation.sdediting table.sdtable td.obsmotivation span.motivationstring span.mathquill-textbox:after,
.structuredderivation.sdediting table.sdtable td.derivmotivation span.motivationstring span.mathquill-textbox:after {
content: " }";
visibility: visible;
}
div.structuredderivation.sdediting td.virgin {
background-color: rgba(170,170,255,0.6);
background-color: #e7fdfa;
}
div.structuredderivation td.term a.addstep {
display: block;
height: 3px;
margin-top: 5px;
margin-bottom: -8px;
background-color: rgba(255,255,170,0.5);
}
div.structuredderivation td.term:hover > a.addstep,
div.structuredderivation td.term > a.addstep:active {
display: block;
height: 7px;
margin-top: 5px;
margin-bottom: -12px;
background-color: rgba(255,255,80,0.5);
overflow: visible;
}
div.structuredderivation td.term a.addstep span {
display: none;
}
div.structuredderivation tr:hover > td.term > a.addstep span {
display: block;
position: absolute;
right: 3em;
margin-top: -0.75em;
}
div.structuredderivation td > .sdbeforebuttons {
display: none;
position: absolute;
left: -0.5em;
margin-top: -0.4em;
}
div.structuredderivation td > .sdafterbuttons {
display: none;
position: absolute;
right: 1.5em;
margin-top: -1.5em;
}
div.structuredderivation td .sdbeforebuttons .sdaddbutton,
div.structuredderivation td .sdafterbuttons .sdaddbutton,
div.structuredderivation td .sdaddbutton {
display: block;
text-align: center;
vertical-align: middle;
width: 1.2em;
height: 1.2em;
font-size: 120%;
font-weight: bold;
color: #9f9;
background-color: white;
color: white;
background-color: #445016;
border-radius: 0.75em;
-webkit-border-radius: 0.75em;
-o-border-radius: 0.75em;
float:left;
text-decoration: none;
}
div.structuredderivation td .sdbeforebuttons .sdremovebutton,
div.structuredderivation td .sdafterbuttons .sdremovebutton,
div.structuredderivation td .sdremovebutton {
display: block;
text-align: center;
vertical-align: middle;
width: 1.2em;
height: 1.2em;
font-size: 120%;
font-weight: bold;
color: #f99;
background-color: white;
color: white;
background-color: #a00;
border-radius: 0.75em;
-webkit-border-radius: 0.6em;
-o-border-radius: 0.6em;
float:left;
text-decoration: none;
}
div.structuredderivation td .sdremovebutton:hover {
color: #a00;
box-shadow: 0 0 2px rgba(170,0,0,0.5);
}
div.structuredderivation td .sdaddbutton:hover {
color: #0a0;
box-shadow: 0 0 2px rgba(0,170,0,0.5);
}
div.structuredderivation td .sdremovebutton:hover > span {
color: white;
}
div.structuredderivation td .sdaddbutton:hover > span {
color: white;
}
div.structuredderivation.sdediting tr:hover > td > .sdafterbuttons,
div.structuredderivation.sdediting tr:hover > td > .sdbeforebuttons {
display: block;
}
div.structuredderivation tr td.subder {
vertical-align: top;
}
#mathbuttonwrapper {
position: absolute;
right: 6.5em;
}
#mathbuttonpanel {
position: fixed;
background: white;
border: 1px solid #faa;
width: auto;
z-index: 8000;
}
#mathbuttonpanel {
top: 8em;
/* right: 0; */
}
#mathbuttonpanel .buttontablelist {
list-style: none;
margin: 0;
padding: 0;
}
#mathbuttonpanel .buttoncatwrapper {
position: absolute;
top: 0;
left: 0;
}
#mathbuttonpanel .buttontablelist li.buttontableicon {
margin: 0px;
padding: 2px;
border: 1px solid #faa;
position: relative;
font-size: 160%;
}
#mathbuttonpanel .buttontablelist li.buttontableicon:hover {
background-color: #faa;
}
#mathbuttonpanel .buttontablelist li.buttontableicon > a {
display: block;
text-align: center;
}
#mathbuttonpanel .buttontablelist li.buttontableicon > a {
text-decoration: none;
}
#mathbuttonpanel .buttontablelist li.buttontableicon > a > span.buttoncategoryname{
display: block;
text-align: center;
font-size: 70%;
}
#mathbuttonpanel .buttontablelist li.buttontableicon:hover .buttonelementtable {
display: block;
}
#mathbuttonpanel .buttontablelist li.buttontableicon .buttonelementtable {
display: none;
position: absolute;
right: 0;
top: 0;
background-color: white;
border: 1px solid #faa;
}
#mathbuttonpanel .buttontablelist li.buttontableicon .buttonelementtable td:hover {
background-color: #faa;
}
#mathbuttonpanel .buttontablelist li.buttontableicon .buttonelementtable td a.buttonlink {
display: block;
text-align: center;
padding: 0.3em 0.5em;
}
#mathbuttonpanel .buttontablelist li.buttontableicon .buttonelementtable td a.buttonlink:hover {
text-decoration: none;
}
.sdediting div.sdsubderivation {
border: 1px dashed transparent;
position: relative;
margin: 0;
padding: 0;
}
.sdediting div.sdsubderivation:hover {
border: 1px dashed #aaa;
border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
}
/**** hide subderivations *************/
tr.sdhidden > td > div.sdsubderivation {
display: none;
}
td.ldots:hover,
td.ldots:hover span {
cursor: pointer;
}
/********* editormenu ****************/
#qededitormenuwrapper {
text-align: left;
position: absolute;
background-color: #fffdB7;
border: 1px solid #aaa;
z-index: 5000;
}
#qededitormenuwrapper ul {
list-style: none;
margin: 0;
padding: 0;
}
#qededitormenuwrapper ul li {
margin: 0;
padding: 0.2em 0.3em;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
#qededitormenuwrapper ul li.selected {
cursor: pointer;
background-color: #ffd500;
}
#qededitormenuwrapper ul li.plus a {
color: #445016;
}
#qededitormenuwrapper ul li.plus.selected {
color: white;
background-color: #445016;
}
#qededitormenuwrapper ul li.plus.selected a {
color: white;
}
#qededitormenuwrapper ul li.minus a {
color: #a00;
}
#qededitormenuwrapper ul li.minus.selected {
color: white;
background-color: #a00;
}
#qededitormenuwrapper ul li.minus.selected a {
color: white;
}
#qededitormenuwrapper ul li .menuoperation {
font-weight: bold;
padding-right: 1em;
}
#qededitormenuwrapper ul li a {
display: block;
}
#qededitormenuwrapper ul li a:hover {
background-color: transparent;
}
#qededitormenuwrapper span.menuname {
display: none;
}
.sdbeforebuttons {
position: relative;
}
.sdbeforebuttons #qededitormenuwrapper {
left: 0;
top: 0;
}
.sdafterbuttons #qededitormenuwrapper {
right: 0;
top: 0;
}
/********* mathquill: text vs. math ****************/
.qededitor .mathquill-textbox.mathquill-editable.hasCursor,
.qededitor .mathquill-editable.mathquill-rendered-math .hasCursor.text {
-ms-box-shadow: #f55 0 0 3px 2px;
-o-box-shadow: #f55 0 0 3px 2px;
-webkit-box-shadow: #f55 0 0 3px 2px;
box-shadow: #f55 0 0 3px 2px;
/* border: 1px solid #faa; */
}
/*.qededitor .relation .mathquill-editable.mathquill-rendered-math.hasCursor,
.qededitor .mathquill-editable.mathquill-rendered-math.hasCursor,
.qededitor .mathquill-editable.mathquill-rendered-math .hasCursor {
border: 1px solid #aaf;
}*/
/*************** MathQuill -tweak **********************/
.mathquill-embedded-latex.mathquill-rendered-math,
.mathquill-editable.mathquill-rendered-math {white-space: pre-wrap;}
.mathquill-embedded-latex.mathquill-rendered-math *,
.mathquill-editable.mathquill-rendered-math *,
.mathquill-editable.mathquill-textbox .mathquill-rendered-math span
{white-space: nowrap;}
.mathquill-rendered-math .text span {white-space: normal;}
/********* Plugin system **************************/
div.pluginbuttons {
display: inline-block;
border: 2px solid #faa;
border-bottom: none;
border-radius: 8px 8px 0 0;
margin: 0 0.5em;
background-color: white;
}
div.pluginbuttons ul {
position: absolute;
background-color: white;
border: 2px solid #faa;
list-style: none;
margin: 0;
padding: 0;
display: none;
border-top: none;
margin-left: -2px;
z-index: 50;
}
div.pluginbuttons:hover ul {
display: block;
}
div.pluginbuttons ul li a.pluginbutton {
display: block;
padding: 0.2em 0.5em;
}
div.pluginbuttons ul li a.pluginbutton:hover {
background-color: #faa;
}
div.pluginbuttons ul li a.pluginbutton img {
border: none;
margin: 0.2em 0.6em 0.2em 0.2em;
vertical-align: middle;
}
/*************** TiddlyWiki specific *************************/
.tiddler #mathbuttonpanel {
top: 10em;
right: auto;
}
.qedcontexttiddlywiki .structuredderivation {
-moz-border-image: url([[paperrip.png]]) 8 1 8 1 repeat repeat;
-webkit-border-image: url([[paperrip.png]]) 8 1 8 1 repeat repeat;
-o-border-image: url([[paperrip.png]]) 8 1 8 1 repeat repeat;
border-image: url([[paperrip.png]]) 8 1 8 1 fill repeat repeat;
border-style: solid;
}
.qedcontexttiddlywiki .structuredderivation .button.command_qededit {
background: transparent url('[[button-edit.png.base64]]') center center no-repeat;
}
.qedcontexttiddlywiki .structuredderivation a.button.command_qedclose.command_editorclose {
background: transparent url('[[button-close.png.base64]]') center center no-repeat;
}
/*}}}*/
/*
SdeditButton: #ffd42a
SdeditSelected: #ffd42a
SdeditHover: #ffdd55
SdeditBg: #ffeeaa
SdeditButtonbgYellow: iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAtSURBVAiZY/j/bsV/Job/vxmYGP7/YcBk4ZSAsxjwyuI3lAFN4i8DEwMDAwMA85A5NzMeKVUAAAAASUVORK5CYII=
SdeditButtonTask: iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADySURBVEiJ7ZU9isJAFMd/CTlDrBftPYCyYYsUAStLwT72Vh7AK6y9xR4hxYDixwVSR1GwsvACCeZZWIk4M83ACg68Zh6/9/HnzRtPLn+CwxMgpcv4BEjlOoHzDj4SmRLU/0SibLlHrQ8AxN9fJD9NK86T09j40EYTxWyeP9ylwza/09iYwEdKdJYtiqfgALN5TrYotCxS4iMVOlOb48vq1OaoZZHKYorkqvcZeJ+6RGdxJ3wJx51Qy1JbSJREIemg9RQ8HbRIotAokSe7vtW6zlZn1PZ8r7zbIIkaNhieFD3X/8Hb7yLnHbhfdm8vEU6nlBuVcNQICqUtEgAAAABJRU5ErkJggg==
SdeditButtonAssumption: iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMASURBVEiJ7ZVbSJNhGMd/OzSn23JqLvOUNUEtzQpMvbFFQWFRN2F0uCikc2BB3UQnKKGrjOrCIAiMiC6K6qKyg1ZkBWIHNTMpRVNn2nJz6ty3ua8Lafpuk7zZXS88N//n/77P93+///O8Ctl2SyaMS40shfN81MiecBcIu4LQBXr7HCQmRM/okB6rg6R5oblKZA+BUfu6lXMVj4Pw6eJcxWOe1H4OmVPI1nLBRYMOFzmWS7x+sIe0lJgZKWjv/E3B+kqaX5RhmqMLUOCTmBrlFc8pXp1OWpKOwNx0sTBFz7pVZs5eeBaUU8jdx/0KnMMSptyLNNfsxjx/8uu9Xh837jTT0GTF4/GRu8jEri25RGrVfk7jl37yiq/T33iYaEPE1H8g8Tce1rQSHxeJOVXHVHzl5irGxz3s3Z5DQryWstNP2XnkvsBZkmkkJjqC6to2ARdc9Kb+B9kZsQQ6q/xYAZbCZAByMvL41PKT+9Xf8I27USoVft6y7HjeNvygZMMCPyY0WrfViXG2hsDmsxTMFbBYowa3NI7dMUKscfI64owaevqcAldQ4PF60euUQQpkGeobB7hX3cmzul4GbK4J3CeBPKlArYJBhyTsF1yUaNLyy+YSXFD/0UpK4S0OnqijpDiZd3fWUlqSPrE7wDH2oTESTRECJjRallnPt84hoVEqb7bS0zfKlTPLWZplQKnw8tvu+qtZ4Hb1DJNlNgiY4KL1ljm0dTgZsDn9WHzshBWHR1wgS9gdI1Td7QBAcrv9vNFRF01f7WxaYxJcJBRIT9VgyY/j2u3vfmzf1mQMOjWb9r5l4546LNtecnBHGgDHzn+iqdUGssTd6i4s+XGYU2YJBRRy21phVHxoGWJdaQPtNUXoIlUAjLl9PHo1gDZCRVFeDFFaFXXvB9FHqVmaZUCWobDkHVfPLiY30yAYRCF/XRX0op253IE+SsXR0tTAVMhVda+Pju4xTh9KC8qFnKanDiSTNFc942mqUfs4uT9pmmnasuL/m/yPAoT1hvgDjkP2hahU+ocAAAAASUVORK5CYII=
SdeditButtonObservation: iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIySURBVEiJ7ZU7b9NQGIafc+w4CQXMRVXFbWCjwEAH4A8wIAF/AH4CP4KLRCsGLpWCxJROiCkCIaGSAcpAAcEIRSChLgh1QJQkQoTEx+djcOxcbIeFbHySJeec7/N7ntevHCXf7wsTLBfpTvL5uEgwaYGJE0QCv9pdfjTaaK2wVti3x88cEBF+dwzlUmFo/etGM5nd4ZeZ2uIBoJEAJKD+bI0Dc5e5dusJV28sE68PXq/efubk6ZusvPiY2ltYrDN/u87+Y5dYfvouWU8I/G0uWisq82d6R+1bt7K6TqX6mucv19lstPFcYdTaeK5SXcXf6ib7Lja6KXmCUhD/juv8xRprn75x9/pZ9s5MUVl6Q7Egqb64tFaUvP5z+ikSgwJGU7V45RT+9iJewaH2+D0AXkFSfXE5WqFVmOz3UyQGrVUKfXqXC4QgIQobCbg21TdIoJUZsChpDCKLxsTWmOhUpWK+gOOkBAYsUioXHSAMw0jAy7dIa4Ui06IASKdjmMD0BPIJFCASpFOEGETITQdAEPQsKtjcvtAK1nSzUySSjw7Q+jlAKyqzx1pBxGRbJMJYi5qtTo+kAzkf+TAUxAYZKRKDtePfQUxgTCefQAQ7LBChdLvd6FBjLKouHMEYYbefn7YwlOhdjVq02WhjrXDv0RcALpybSQ0fOhh/QU3Komptg5ip2WqnCY4fLfOgMovrgJXxJFk1vVPjaMXDO7PMHS4n80o+nPj/n/wXgbxA/6P6A0vDXjMXbiLgAAAAAElFTkSuQmCC
SdeditButtonStep: iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJqSURBVEiJvZXLTxNRGMV/02npg3ZK20lBHhYb8UUUJUZIfLIw4Q9w4X/l2r/ArQtjdEFwhSaKVkMAH6BSitTSdOiUdmY6M9eFj0QhM4Wk3uQmd3HO/fKd79xzJVF9IOjiCiKsbt5PENHudoGud3C4AnXdQElEDlPAW6IXi18ZyCqUKzr5XIaXhSI3pk/weG6VfC7D5YlhT34AYeG1J89nuXd/nnNjKQyjiWka2LaJmgrzaX3bk4uwCOJ6S9Qjw+3royRiEolYlGTvCEo8wIUzafaaCfz4vhI5juDSuMpvnBIPgGijpkKoqRB+fN8hywEY6g9zVLd5zqCwVELXGyAsNjarvHq7uQ/z8MnKn/P3nV0KS6V/ZvCrxeJWg6pmEI0EOZ3vA6BSbTB+SuHps3VkWeLLpo62u4dtuwxkY7xf01j+WGMwG6G802T21nEKSzqIvv0dtNsmhmFgmSYIC9Ns0Wy12NrWKFd0Pm/UyKZDfFivslHSGB+Ls1Wuo8QDLCyW6FdDmEaLaq1xsIvyw2Hyw+GfZV2LcBCUmEQmGeDi2QThHhnXFcxMZ2gZDsVNjTuzQ9i2oF+NsLK2S9syyQ1G/nKWJNbueqap7QiCstTRQA/C+rooGAA6DPSDsIfPooaNEg92jPd9aMVvBgtvNGam0riu4PVynZtX0jyarzA6FGVqIunJ980itQ/erWr0Rh0M08Q0LVzHolJtIty2bxZJYvWap8I7tTa9URl9zyGbCVFvOChxmbnnGlcnFSLhgI9EPmGlJgFsoj2Aa6HEANfh5IhMJGSD60k/+o+WOyZ1lE//4U/u1ORHXD8AV717Ox+WxDUAAAAASUVORK5CYII=
SdeditButtonPlus: iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFESURBVDiNpZO9SgNREIW/u9lsVpEkhPUHfQhtxDIIVikiik8gxAfQyiaFT2BhY0TsrCPaRrAXJGCw0UYbCVESg+Rnk3stdiMJ3BsImWrgzpw5Z+Zcob6uFVOEjWxN04+NamsfPqsNbkuPICC7tc6iF5+MwUnhkn7qDYDy+TNnxwcmAD0Dn1+sMO/0mpjqxuxAjuaGOqE+jhRA7btFvnCHTzCp6zRwEx0A2vUYjp8AIGbNkN/PsODNjjIolsr0vXcsESC7Q1PcZAeohtLg5r5Mbm9tABBqU75BiiZU738nNipgsJ1e4elqCWl3AWhFmsTiAWi34eDKOQCi0iGbWWbQJ9TrjtaJudMSlvcDgKwmuTjc1JIZc4UhXGW+gtEHdi+CDDGiRIw+EOplQyuhVvcpPtRAwG56nlTCNgBUVqf8jZOcTxN/ks2ACpMzJyMAAAAASUVORK5CYII=
SdeditButtonMinus: iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACTSURBVDiNY/z/dtl/BgoAC8O/75ToZ2Bh+P+DQgModsG/AXcBNAzevP3OMC17CwPLBwIuEuJkSJnoxSAmyoXqgp1rLjJoHH3EwEiErbvWXWSISTWAGQC18f9v4t397w8DTB8Lw3+IC9wCpBlmHpBg4Pj4C6/e3wJsDEn+UgwwfYz/7wQOdEqkOB38H3gXkBB9WAAAeoU/bStsx3oAAAAASUVORK5CYII=
/**/
/*{{{*/
#sdappbox #sdappcontent.sdeditor {
font-size: 150%;
background-color: [[StyleSheetSdeditor::SdeditBg]];
bottom: 5em;
box-shadow: 5px 5px 15px black;
-moz-box-shadow: 5px 5px 15px black;
-webkit-box-shadow: 5px 5px 15px black;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol {
width: 30px;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton {
width: 24px;
height: 24px;
margin: 0;
padding: 0;
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonbgYellow]]') left top repeat-x;
border-top: 1px solid #aaa;
border-left: 1px solid #aaa;
border-right: 1px solid #444;
border-bottom: 1px solid #444;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton.sdaddtask {
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonTask]]') left top repeat-x;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton.sdaddtask.sdhidden {
display: none;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton.sdaddass {
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonAssumption]]') left top repeat-x;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton.sdaddobs {
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonObservation]]') left top repeat-x;
}
#sdappbox #sdappcontent.sdeditor .sdappcontrol div.sdedbutton.sdaddstep {
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonStep]]') left top repeat-x;
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr:hover {
background-color: [[StyleSheetSdeditor::SdeditHover]];
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr:last-child:hover {
background-color: transparent;
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor td.selected {
background-color: [[StyleSheetSdeditor::SdeditSelected]];
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr td {
// position: relative;
padding-top:10px;
padding-bottom: 10px;
padding-left: 20px;
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr td .minusbutton,
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr td .plusbutton {
display: none;
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr:hover td .minusbutton {
display: block;
position: absolute;
width: 16px;
height: 16px;
margin-left: -16px;
margin-top: 10px;
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonMinus]]') left top repeat-x;
border-top: 1px solid #aaa;
border-left: 1px solid #aaa;
border-right: 1px solid #444;
border-bottom: 1px solid #444;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#sdappbox #sdappcontent.sdeditor .sdtable.editor tr:hover td .plusbutton {
display: block;
position: absolute;
width: 16px;
height: 16px;
margin-left: -16px;
margin-top: -8px;
background: [[StyleSheetSdeditor::SdeditButton]] url('data:image/png;base64,[[StyleSheetSdeditor::SdeditButtonPlus]]') left top repeat-x;
border-top: 1px solid #aaa;
border-left: 1px solid #aaa;
border-right: 1px solid #444;
border-bottom: 1px solid #444;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#sdappbox #sdappcontent.sdeditor .sdeditline {
width: 95%;
height: 2em;
}
#sdappbox #sdappcontent.sdeditor .sdeditline input {
display: none;
width: 100%;
padding: 0.2em 0.5em;
margin-bottom: 1em;
border: 1px solid gold;
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
}
#sdappbox #sdappcontent.sdeditor .sdeditline input.editing {
display: inline;
}
#sdappbox #sdappcontent.sdeditor .sdappaction {
overflow: auto;
position: absolute;
top: 4em;
bottom: 10px;
left: 60px;
right: 10px;
}
/*}}}*/
/*{{{*/
/****************************** Table of contents *******************************/
.sdbooktoc {
border: 2px solid #3f4426;
background-color: #cddd7d;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-o-border-radius: 8px;
}
.sdbooktoc h1 {
font-size: 250%;
background-color: #3f4426;
color: white;
margin: 0;
padding: 1em 0.3em;
text-align: center;
border-radius: 7px 7px 0 0;
-moz-border-radius: 7px 7px 0 0;
-webkit-border-radius: 7px 7px 0 0;
-o-border-radius: 7px 7px 0 0;
}
.sdbooktoc h1 a {
color: #3f4426;
font-style: normal;
}
.sdbooktoc ol {
margin-left: 2em;
}
.sdbooktoc ol li {
font-size: 150%;
font-weight: bold;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
.sdbooktoc ol li ul li {
font-size: 70%;
font-weight: normal;
}
div[tags~="sdtoc"] {
max-width: 70em;
}
/**************************** Chapter ************************************/
div[tags~="sdbookchapter"] div.title {
font-size: 200%;
text-align: center;
}
div[tags~="sdbookchapter"] {
max-width: 70em;
text-align: justify;
}
/****
* History
*****/
.sdbookhistory {
border-top: 4px double #333;
}
.sdbookhistory h3 {
text-align: center;
}
/**************************** Hidden ***********************************/
.sdbookhidden {
display: none;
margin: 0;
padding: 0;
}
/**************************** Example ***********************************/
.sdbookexample {
display: block;
max-width: 60em;
border: 1px solid #aaa;
background-color: white;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
padding: 0 10px 10px 10px;
margin: 2em 0.5em;
}
.sdbookexample h1 {
font-size: 160%;
background-color: #e7ffb7;
color: black;
margin: 0 -10px 10px -10px;
padding: 0.4em 0.1em;
text-align: center;
border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
text-sahdow: 2px 2px 2px white;
border-bottom: 3px solid #3f4426;
}
.sdbookexample.sdclickable h1 {
cursor: pointer;
}
/**************************** Assignment ***********************************/
.sdbookassignment {
max-width: 60em;
border: 1px solid #aaa;
background-color: white;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
padding: 0 10px 10px 10px;
margin: 2em 0.5em;
}
.sdbookassignment h1 {
font-size: 160%;
background-color: #e7b7ff;
color: black;
margin: 0 -10px 10px -10px;
padding: 0.4em 0.1em;
text-align: center;
border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
text-sahdow: 2px 2px 2px white;
border-bottom: 3px solid #3f2644;
}
.sdbookassignment.sdclickable h1 {
cursor: pointer;
}
/**************************** Theory ***********************************/
.sdbooktheory {
max-width: 60em;
border: 1px solid #aaa;
background-color: #fffdb7;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-o-border-radius: 5px;
padding: 0 10px 10px 10px;
margin: 2em 0.5em;
}
.sdbooktheory h1 {
font-size: 160%;
background-color: #ffd500;
color: black;
margin: 0 -10px 10px -10px;
padding: 0.4em 0.1em;
text-align: center;
border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
text-sahdow: 2px 2px 2px #555;
border-bottom: none;
}
/************************* sdtable ******************************************/
table.sdtable {
border-collapse: collapse;
border: none;
margin: 0;
padding: 0.3em 0;
background: transparent url([[papersquare.png]]) left top repeat;
width: 97%;
}
table.sdtable table.sdtable {
background: none;
}
.sdtable td:first-child {
min-width: 3em;
text-align: center;
}
.sdtable td:first-child+td {
min-width: 20em;
padding: 0.3em 1em;
}
.sdtable tr,
.sdtable td {
border: none;
}
table.sdtable td {
vertical-align: text-top;
}
.button.command_editSD,
.button.command_qededit {
display: block;
background: transparent url('[[button-edit.png.base64]]') center center no-repeat;
width: 24px;
height: 24px;
}
.button.command_editSD.locked {
display: none;
}
.button.command_editorclose {
display: block;
background: transparent url('[[button-close.png.base64]]') center center no-repeat;
width: 24px;
height: 24px;
}
#sdappbox .sdapp_close,
#sdappbox .editor_close {
display: block;
position: absolute;
background: transparent url('[[button-close.png.base64]]') center center no-repeat;
width: 24px;
height: 24px;
top: 0;
right: 0;
margin-right: -12px;
margin-top: -12px;
}
/*
table.sdtable td.motivation span.mathquill-textbox:before,
table.sdtable td.obsmotivation span.mathquill-textbox:before,
*/
table.sdtable td.motivation span.motivationstring:before,
table.sdtable td.obsmotivation span.motivationstring:before,
table.sdtable td.derivmotivation span.motivationstring:before {
content: "{ ";
}
/*
table.sdtable td.motivation span.mathquill-textbox:after,
table.sdtable td.obsmotivation span.mathquill-textbox:after,
*/
table.sdtable td.motivation span.motivationstring:after,
table.sdtable td.obsmotivation span.motivationstring:after,
table.sdtable td.derivmotivation span.motivationstring:after {
content: " }";
visibility: visible;
}
/************************* Exercise ***********************************************/
span.sdbuttonexercise {
display: inline-block;
position: relative;
width: 330px;
height: 60px;
background: transparent url('[[button-exercise.png]]') left top no-repeat;
}
span.sdbuttonexercise .sdbuttonlabel {
padding: 1px 8px;
border-left: 2px solid black;
border-right: 2px solid black;
border-top: 2px solid white;
border-bottom: none;
color: red;
font-weight: bold;
position: absolute;
top: 0px;
right: 15px;
}
span.sdbuttonexercise .exclabel {
position: absolute;
left: 100px;
bottom: 10px;
font-size: 200%;
font-weight: bold;
}
/************************* Layout ***********************************************/
.sdcenter {
display: block;
text-align: center;
}
/**************************************************
* EbookApp
* fracCalc
**************************************************/
#ebookappwrapper {
z-index: 10000;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: transparent;
padding: 2em;
}
#ebookappwrapper .ebookapp {
width: 50em;
margin: 5em auto;
border: 1px solid black;
border-radius: 8px;
background-color: #d9e5f5;
padding: 3em;
}
#ebookappwrapper .gameinfo {
widht: 10em;
float: left;
}
#ebookappwrapper .questionpart {
margin-left: 13em;
}
.ebookapp .questionpart {
margin-left: 160px;
padding: 2em;
background-color: white;
}
.ebookapp .questionpart h1.questionhead {
color: black;
font-size: 150%;
}
.ebookapp .questionpart .question {
}
.ebookapp .questionpart .question .calculation {
margin: 1.5em 2.5em;
padding: 1.5em 0 1.5em 2em;
font-size: 300%;
line-height: 1.5em;
background: transparent;
}
.ebookapp .questionpart .question .calculation .sd-division td {
text-align: center;
padding: 0.5em;
}
.ebookiapp .questionpart .question .calculation .sd-division td.divided {
border-bottom: 2px solid black;
}
.ebookapp .questionpart .question .calculation input.igresult {
font-size: 100%;
}
.ebookapp .gameinfo {
float: left;
width: 130px;
margin: 0;
background-color: #d9e5f5;
}
.ebookapp .gameinfo .eapnts {
text-align: center;
}
.ebookapp .gameinfo .eathispoints {
font-size: 180%;
}
.ebookapp table.sd-fraction {
text-align: center;
}
.ebookapp table.sd-fraction td {
text-align: center;
vertical-align: middle;
width: auto;
padding: 0.1em 0.3em;
}
.ebookapp table.sd-fraction td.numerator {
border-bottom: 1px solid black;
padding-left: 1em;
padding-right: 1em;
}
.ebookapp table.sd-fraction td.numerator.integer {
border-bottom: none;
}
.ebookapp input.eappsubmit {
width: 100%;
}
.ebookapp input.earesult {
width: 4em;
text-align: center;
border: none;
background-color: #afa;
}
.ebookapp table.sd-table tbody tr td:first-child {
width: 3em;
text-align: center;
}
.ebookapp table.sd-table tbody tr td table.sd-fraction td:first-child {
width: auto;
}
.ebookapp input.redalert {
background-color: #faa;
}
.ebookapp.fracCalcTest input.redalert {
background-color: #afa;
}
.ebookapp sup.sup-divider {
color: red;
position: absolute;
/* margin-right: -1.8em; */
margin-left: 0.3em;
margin-top: -0.5em;
font-size: 80%;
}
.ebookapp .sd-mot .resultiszero {
display: none;
}
.ebookapp .infoboxp {
border: 1px dashed #666;
padding: 0.5em;
background-color: white;
}
.ebookapp .infobox {
font-weight: bold;
}
.ebookapp .infobox.wronginfo {
color: red;
}
.ebookapp .infobox.correctinfo {
color: green;
}
.ebookapp .gameinfo .eaminuspoints {
color: red;
}
.ebookapp .gameinfo .eathispoints {
font-weight: bold;
}
.ebookapp input[type="submit"] {
background: #dae5f5 url([[button-bg.png]]) left bottom repeat-x;
min-height: 32px;
padding-left: 1em;
padding-right: 1em;
border: 1px solid black;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
font-weight: bold;
}
.ebookapp .gameinfo input[type="submit"] {
width: 95%;
margin: auto;
}
.ebookapp input.showsd {
background: #dae5f5 url([[button-bg.png]]) left bottom repeat-x;
min-height: 32px;
padding-left: 32px;
border: 1px solid black;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
font-weight: bold;
}
/*}}}*/
/***
|Name|SvgImgPlugin|
|Version|0.1|
|Author|Petri Salmela & Petri Sallasmaa|
|License|WTFPL|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Macro displays inline svg-images form given tiddler.|
!code
***/
//{{{
config.macros.svgimg = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1 || !store.tiddlerExists(params[0])){
wikify('Missing image', place);
return false;
}
var classes = params[1] || '';
var svgtiddler = params[0];
var svgdata = store.getTiddlerText(svgtiddler + '##data');
var link = params[2] || store.getTiddlerText(svgtiddler + '##link');
if (svgdata){
wikify('<html><div class="svgimg"></div></html>', place, null, tiddler);
var imgplace = jQuery(place).find('.svgimg:last');
imgplace.addClass(classes).html(svgdata);
if (link){
imgplace.wrap('<a href="'+link+'" target="blank_" style="display: inline-block;"></a>');
}
} else {
wikify('Missing image', place);
return false;
}
}
}
//}}}
chkAnimate: false
chkAutoSave: true
chkSaveBackups: false
chkSinglePageMode: false
chkSinglePagePermalink: false
!themeid
academic
!name
Academic theme
!css
/*{{{*/
/*body[ebooktheme="academic"] .bookpage {max-width: 55em;}*/
body[ebooktheme="academic"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="academic"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="academic"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="academic"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fdfdfd;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="academic"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="academic"] #pageTwoWrapper #pageTwoNavi
{background-color: #ddd;}
body[ebooktheme="academic"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fdfdfd; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="academic"] #mainMenu {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="academic"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="academic"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(0,0,0,1);}
body[ebooktheme="academic"] #contentWrapper .header {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="academic"] .bookpage h1.ebooktitle {color: #000; border-bottom: 2px solid #000;}
body[ebooktheme="academic"] .ebookbox .sdbookexample h1,
body[ebooktheme="academic"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
}
body[ebooktheme="academic"] .ebookbox .sdbookexample,
body[ebooktheme="academic"] .ebookbox .sdbooktheory {
background-color: transparent;
border: none;
box-shadow: none;
margin-left: 0;
}
body[ebooktheme="academic"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="academic"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="academic"] .ebookimage .imgcaption,
body[ebooktheme="academic"] .functiongraph .graphcaption {
border: 1px solid black;
background-color: #eee;
text-align: left;
}
body[ebooktheme="academic"] ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #eee;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="academic"] .geocaption {
background-color: #eee;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="academic"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="academic"] #rightmenu .ebookshelfcontainer {
border: 4px solid black;
}
body[ebooktheme="academic"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="academic"] #rightmenu .ebookshelfcontainer h1 {
color: black;
border-bottom: 3px solid black;
}
body[ebooktheme="academic"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_black.png]]) left top no-repeat;
}
body[ebooktheme="academic"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_black.png]]) right top no-repeat;
}
body[ebooktheme="academic"] .ebookshelf_apps ul.applist {
background-color: black;
}
/*}}}*/
!themeid
defaultserif
!name
Default Serif theme
!css
/*{{{*/
@font-face {
font-family: Baskerville;
src: url( ./data/fonts/OpenBaskerville-0.0.53.otf ) format("opentype");
}
body[ebooktheme="defaultserif"] .bookpage {
font-family: serif, Baskerville, "Times New Roman";
}
body[ebooktheme="defaultserif"] .bookpage h1,
body[ebooktheme="defaultserif"] .bookpage h2,
body[ebooktheme="defaultserif"] .bookpage h3 {
font-family: helvetica, sans;
}
/*}}}*/
!themeid
flame
!name
Flame
!author
Pesasa
!css
/*{{{*/
/*body[ebooktheme="flame"] .bookpage {max-width: 55em;}*/
body[ebooktheme="flame"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="flame"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="flame"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="flame"] #displayArea {border-image:none; -moz-border-image:none; background-color: white; left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="flame"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="flame"] #pageTwoWrapper #pageTwoNavi
{background-color: #ddd;}
body[ebooktheme="flame"] #sidePage {border-image: none; -moz-border-image: none; background-color: white; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="flame"] #mainMenu {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="flame"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="flame"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(0,0,0,1);}
body[ebooktheme="flame"] #contentWrapper .header {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="flame"] .bookpage h1.ebooktitle {color: black; border-bottom: 2px solid black;}
body[ebooktheme="flame"] .ebookbox .sdbookexample h1,
body[ebooktheme="flame"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="flame"] .ebookbox .sdbookexample,
body[ebooktheme="flame"] .ebookbox .sdbooktheory {
position: relative;
background-color: white;
border: 1px solid black;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="flame"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: white;
text-shadow: 1px 1px 1px #eee;
background: rgb(76,76,76); /* Old browsers */
background: -moz-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(76,76,76,1)), color-stop(12%,rgba(89,89,89,1)), color-stop(25%,rgba(102,102,102,1)), color-stop(39%,rgba(71,71,71,1)), color-stop(50%,rgba(44,44,44,1)), color-stop(51%,rgba(0,0,0,1)), color-stop(60%,rgba(17,17,17,1)), color-stop(76%,rgba(43,43,43,1)), color-stop(91%,rgba(28,28,28,1)), color-stop(100%,rgba(19,19,19,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="flame"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
background: rgb(254,204,177); /* Old browsers */
background: -moz-linear-gradient(top, rgba(254,204,177,1) 0%, rgba(241,116,50,1) 5%, rgba(252,169,53,1) 23%, rgba(255,221,53,1) 44%, rgba(247,169,51,1) 80%, rgba(234,85,7,1) 99%, rgba(251,149,94,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,204,177,1)), color-stop(5%,rgba(241,116,50,1)), color-stop(23%,rgba(252,169,53,1)), color-stop(44%,rgba(255,221,53,1)), color-stop(80%,rgba(247,169,51,1)), color-stop(99%,rgba(234,85,7,1)), color-stop(100%,rgba(251,149,94,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(254,204,177,1) 0%,rgba(241,116,50,1) 5%,rgba(252,169,53,1) 23%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 80%,rgba(234,85,7,1) 99%,rgba(251,149,94,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(254,204,177,1) 0%,rgba(241,116,50,1) 5%,rgba(252,169,53,1) 23%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 80%,rgba(234,85,7,1) 99%,rgba(251,149,94,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(254,204,177,1) 0%,rgba(241,116,50,1) 5%,rgba(252,169,53,1) 23%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 80%,rgba(234,85,7,1) 99%,rgba(251,149,94,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(254,204,177,1) 0%,rgba(241,116,50,1) 5%,rgba(252,169,53,1) 23%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 80%,rgba(234,85,7,1) 99%,rgba(251,149,94,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feccb1', endColorstr='#fb955e',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="flame"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[fire_ball.png]]) top right no-repeat;
width: 60px;
height: 67px;
position: absolute;
right: -20px;
top: -15px;
content: " ";
}
body[ebooktheme="flame"] .ebookbox .sdbookexample h1:after {
background: transparent url([[racing_flame.png]]) top right no-repeat;
width: 92px;
height: 40px;
position: absolute;
right: -92px;
top: -8px;
content: " ";
}
body[ebooktheme="flame"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="flame"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="flame"] .ebookimage .imgcaption,
body[ebooktheme="flame"] .functiongraph .graphcaption {
border: 1px solid #a00;
background-color: #fbf6e4;
border-bottom: 4px solid #a00;
border-radius: 0 0 5px 5px;
}
body[ebooktheme="flame"] ul.jessiebuttons {
border: 1px solid #a00;
border-top: none;
border-bottom: 4px solid #a00;
background-color: #fbf6e4;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="flame"] .geocaption {
background-color: #fed834;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="flame"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="flame"] #rightmenu .ebookshelfcontainer {
border: 4px solid black;
}
body[ebooktheme="flame"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="flame"] #rightmenu .ebookshelfcontainer h1 {
color: black;
border-bottom: 3px solid black;
}
body[ebooktheme="flame"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_black.png]]) left top no-repeat;
}
body[ebooktheme="flame"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_black.png]]) right top no-repeat;
}
body[ebooktheme="flame"] .ebookshelf_apps ul.applist {
background-color: black;
}
body[ebooktheme="flame"] .ebook-button,
body[ebooktheme="flame"] .ui-widget.ui-button,
body[ebooktheme="flame"] .ui-widget h3,
body[ebooktheme="flame"] .ui-slider a.ui-slider-handle {
border-color: black;
background: rgb(249,51,24); /* Old browsers */
background: -moz-linear-gradient(top, rgba(249,51,24,1) 0%, rgba(239,40,4,1) 5%, rgba(252,169,53,1) 28%, rgba(255,221,53,1) 44%, rgba(247,169,51,1) 73%, rgba(239,10,2,1) 89%, rgba(168,59,5,1) 97%, rgba(247,17,9,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(249,51,24,1)), color-stop(5%,rgba(239,40,4,1)), color-stop(28%,rgba(252,169,53,1)), color-stop(44%,rgba(255,221,53,1)), color-stop(73%,rgba(247,169,51,1)), color-stop(89%,rgba(239,10,2,1)), color-stop(97%,rgba(168,59,5,1)), color-stop(100%,rgba(247,17,9,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(249,51,24,1) 0%,rgba(239,40,4,1) 5%,rgba(252,169,53,1) 28%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 73%,rgba(239,10,2,1) 89%,rgba(168,59,5,1) 97%,rgba(247,17,9,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(249,51,24,1) 0%,rgba(239,40,4,1) 5%,rgba(252,169,53,1) 28%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 73%,rgba(239,10,2,1) 89%,rgba(168,59,5,1) 97%,rgba(247,17,9,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(249,51,24,1) 0%,rgba(239,40,4,1) 5%,rgba(252,169,53,1) 28%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 73%,rgba(239,10,2,1) 89%,rgba(168,59,5,1) 97%,rgba(247,17,9,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(249,51,24,1) 0%,rgba(239,40,4,1) 5%,rgba(252,169,53,1) 28%,rgba(255,221,53,1) 44%,rgba(247,169,51,1) 73%,rgba(239,10,2,1) 89%,rgba(168,59,5,1) 97%,rgba(247,17,9,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f93318', endColorstr='#f71109',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="flame"] .ui-widget h3.ui-state-active {
background: #FBEFCB none left top no-repeat;
}
body[ebooktheme="flame"] .ui-accordion-content,
body[ebooktheme="flame"] .ui-widget-content {
background: #FBF5E3 none left top no-repeat;
}
/*}}}*/
!themeid
notelexia
!name
Notelexia
!author
Pesasa
!css
/*{{{*/
@font-face {
font-family: 'eulexia';
src: url([[eulexia.ttf]]) format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: intuitive ;
src: url( ./data/fonts/intuitive.ttf ) format("truetype");
}
@font-face {
font-family: Baskerville;
src: url( ./data/fonts/OpenBaskerville-0.0.53.otf ) format("opentype");
}
body[ebooktheme="notelexia"] .bookpage {font-family: eulexia;}
body[ebooktheme="notelexia"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="notelexia"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="notelexia"] {border-image:none; -moz-border-image:none; -webkit-border-image: none; -o-border-image: none; background: #a7a none;}
body[ebooktheme="notelexia"] #displayArea {border-image:none; -moz-border-image:none; -webkit-border-image: none; -o-border-image: none; background-color: white; left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="notelexia"] #sidePage {border-image: none; -moz-border-image: none; -webkit-border-image: none; -o-border-image: none; background-color: white; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="notelexia"] #displayArea, body[ebooktheme="notelexia"] #sidePage {/*box-shadow: 20px 20px 50px black;*/}
body[ebooktheme="notelexia"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="notelexia"] #pageTwoWrapper #pageTwoNavi
{background-color: #a775a7;}
body[ebooktheme="notelexia"] #ebookshadow {box-shadow: none;}
body[ebooktheme="notelexia"] #mainMenu {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="notelexia"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="notelexia"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(0,0,0,1);}
body[ebooktheme="notelexia"] #contentWrapper .header {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="notelexia"] .bookpage h1.ebooktitle {color: black; border-bottom: 2px solid black; font-family: eulexia;}
body[ebooktheme="notelexia"] .ui-widget {font-family: eulexia;}
body[ebooktheme="notelexia"] .ebookbox .sdbookexample h1,
body[ebooktheme="notelexia"] .ebookbox .sdbooktheory h1 {
font-family: eulexia;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="notelexia"] .ebookbox .sdbooktheory {
position: relative;
background: #fefecb url([[note_pad.png]]) bottom right no-repeat;
border: 1px solid #eadb37;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
-ms-border-radius: 0;
-o-border-radius: 0;
box-shadow: 3px 3px 8px #999;
margin: 0.2em 2em;
/*
transform: rotate(-0.5deg);
-ms-transform:rotate(-0.5deg);
-moz-transform:rotate(-0.5deg);
-webkit-transform:rotate(-0.5deg);
-o-transform:rotate(-0.5deg);
*/
}
body[ebooktheme="notelexia"] .ebookbox .sdbookexample {
position: relative;
background-color: white;
border: none;
box-shadow: none;
margin: 0.2em 0em;
}
body[ebooktheme="notelexia"] .ebookbox .sdbooktheory h1 {
font-family: eulexia;
padding: 0.6em 1em 0 1em;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
}
body[ebooktheme="notelexia"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
font-family: eulexia;
}
body[ebooktheme="notelexia"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="notelexia"] .ebookboxnumber {
display: block;
}
body[ebooktheme="notelexia"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="notelexia"] .ebookimage .imgcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="notelexia"] .functiongraph .graphcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="notelexia"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="notelexia"] #rightmenu .ebookshelfcontainer {
border: 4px solid #a7a;
}
body[ebooktheme="notelexia"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="notelexia"] #rightmenu .ebookshelfcontainer h1 {
color: #a7a;
border-bottom: 3px solid #a7a;
}
body[ebooktheme="notelexia"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_notelexia.png]]) left top no-repeat;
}
body[ebooktheme="notelexia"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_notelexia.png]]) right top no-repeat;
}
body[ebooktheme="notelexia"] .ebookshelf_apps ul.applist {
background-color: #a7a;
}
/*}}}*/
!themeid
notes
!name
Notes
!author
Pesasa
!css
/*{{{*/
@font-face {
font-family: intuitive ;
src: url( ./data/fonts/intuitive.ttf ) format("truetype");
}
@font-face {
font-family: Baskerville;
src: url( ./data/fonts/OpenBaskerville-0.0.53.otf ) format("opentype");
}
/*body[ebooktheme="notes"] .bookpage {max-width: 55em;}*/
body[ebooktheme="notes"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="notes"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="notes"] {border-image:none; -moz-border-image:none; -webkit-border-image: none; -o-border-image: none; background: #a7a none;}
body[ebooktheme="notes"] #displayArea {border-image:none; -moz-border-image:none; -webkit-border-image: none; -o-border-image: none; background-color: white; left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="notes"] #sidePage {border-image: none; -moz-border-image: none; -webkit-border-image: none; -o-border-image: none; background-color: white; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="notes"] #displayArea, body[ebooktheme="notes"] #sidePage {/*box-shadow: 20px 20px 50px black;*/}
body[ebooktheme="notes"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="notes"] #pageTwoWrapper #pageTwoNavi
{background-color: #a775a7;}
body[ebooktheme="notes"] #ebookshadow {box-shadow: none;}
body[ebooktheme="notes"] #mainMenu {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="notes"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="notes"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(0,0,0,1);}
body[ebooktheme="notes"] #contentWrapper .header {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="notes"] .bookpage h1.ebooktitle {color: black; border-bottom: 2px solid black; font-family: Baskerville, Times New Roman, serif;}
body[ebooktheme="notes"] .ebookbox .sdbookexample h1,
body[ebooktheme="notes"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="notes"] .ebookbox .sdbooktheory {
position: relative;
background: #fefecb url([[note_pad.png]]) bottom right no-repeat;
border: 1px solid #eadb37;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
-ms-border-radius: 0;
-o-border-radius: 0;
box-shadow: 3px 3px 8px #999;
margin: 0.2em 2em;
/*
transform: rotate(-0.5deg);
-ms-transform:rotate(-0.5deg);
-moz-transform:rotate(-0.5deg);
-webkit-transform:rotate(-0.5deg);
-o-transform:rotate(-0.5deg);
*/
}
body[ebooktheme="notes"] .ebookbox .sdbookexample {
position: relative;
background-color: white;
border: none;
box-shadow: none;
margin: 0.2em 0em;
}
body[ebooktheme="notes"] .ebookbox .sdbooktheory h1 {
font-family: intuitive, verdana, helvetica, sans-serif;
padding: 0.6em 1em 0 1em;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
}
body[ebooktheme="notes"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
font-family: Baskerville, Times New Roman, serif;
}
body[ebooktheme="notes"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="notes"] .ebookboxnumber {
display: block;
}
body[ebooktheme="notes"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="notes"] .ebookimage .imgcaption,
body[ebooktheme="notes"] .functiongraph .graphcaption {
background-color: #ffa;
border: 1px solid black;
border-radius: 5px;
}
body[ebooktheme="notes"] ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #ffe;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="notes"] .geocaption {
background-color: #ffa;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="notes"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="notes"] #rightmenu .ebookshelfcontainer {
border: 4px solid #a7a;
}
body[ebooktheme="notes"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="notes"] #rightmenu .ebookshelfcontainer h1 {
color: #a7a;
border-bottom: 3px solid #a7a;
}
body[ebooktheme="notes"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_notes.png]]) left top no-repeat;
}
body[ebooktheme="notes"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_notes.png]]) right top no-repeat;
}
body[ebooktheme="notes"] .ebookshelf_apps ul.applist {
background-color: #a7a;
}
/*}}}*/
!themeid
pink
!name
Pink
!author
Pesasa
!css
/*{{{*/
/*body[ebooktheme="pink"] .bookpage {max-width: 55em;}*/
body[ebooktheme="pink"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="pink"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="pink"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="pink"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="pink"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="pink"] #pageTwoWrapper #pageTwoNavi
{background-color: #ffb1b1;}
body[ebooktheme="pink"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fee; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="pink"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="pink"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="pink"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="pink"] #contentWrapper .header {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="pink"] .bookpage h1.ebooktitle {color: #a00; border-bottom: 2px solid #a00;}
body[ebooktheme="pink"] .ebookbox .sdbookexample h1,
body[ebooktheme="pink"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="pink"] .ebookbox .sdbookexample,
body[ebooktheme="pink"] .ebookbox .sdbooktheory {
background-color: transparent;
border: none;
box-shadow: none;
margin-left: 0;
}
body[ebooktheme="pink"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="pink"] .ebookbox .ebookimage {
/* float:right; */
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="pink"] .ebookimage .imgcaption,
body[ebooktheme="pink"] .functiongraph .graphcaption {
background-color: #faa;
border: 1px solid black;
border-radius: 5px;
}
body[ebooktheme="pink"] ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #fee;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="pink"] .geocaption {
background-color: #faa;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="pink"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="pink"] #rightmenu .ebookshelfcontainer {
border: 4px solid #aa0000;
}
body[ebooktheme="pink"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="pink"] #rightmenu .ebookshelfcontainer h1 {
color: #a00;
border-bottom: 3px solid #a00;
}
body[ebooktheme="pink"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_pink.png]]) left top no-repeat;
}
body[ebooktheme="pink"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_pink.png]]) right top no-repeat;
}
body[ebooktheme="pink"] .ebookshelf_apps ul.applist {
background-color: #a00;
}
body[ebooktheme="pink"] .ebook-button,
body[ebooktheme="pink"] .ui-widget.ui-button,
body[ebooktheme="pink"] .ui-widget h3,
body[ebooktheme="pink"] .ui-slider a.ui-slider-handle {
border-color: rgba(255,170,170,1);
background: rgb(252,236,252); /* Old browsers */
background: -moz-linear-gradient(top, rgba(252,236,252,1) 0%, rgba(255,163,163,1) 50%, rgba(255,130,130,1) 51%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(252,236,252,1)), color-stop(50%,rgba(255,163,163,1)), color-stop(51%,rgba(255,130,130,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcecfc', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="pink"] .ui-widget h3.ui-state-active {background: #FCE0EE none left top no-repeat;}
body[ebooktheme="pink"] .ui-accordion-content,
body[ebooktheme="pink"] .ui-widget-content {
background: #FCF3F8 none left top no-repeat;
}
/*}}}*/
!themeid
roselexia
!name
Roselexia
!author
Pesasa
!css
/*{{{*/
@font-face {
font-family: 'eulexia';
src: url([[eulexia.ttf]]) format('truetype');
font-weight: normal;
font-style: normal;
}
body[ebooktheme="roselexia"] .bookpage {font-family: eulexia;}
body[ebooktheme="roselexia"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="roselexia"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="roselexia"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="roselexia"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="roselexia"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="roselexia"] #pageTwoWrapper #pageTwoNavi
{background-color: #ffb1b1;}
body[ebooktheme="roselexia"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fee; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="roselexia"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="roselexia"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="roselexia"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="roselexia"] #contentWrapper .header {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="roselexia"] .bookpage h1.ebooktitle {color: #a00; border-bottom: 2px solid #a00; font-family: eulexia;}
body[ebooktheme="roselexia"] .ui-widget {font-family: eulexia;}
body[ebooktheme="roselexia"] .ebookbox .sdbookexample h1,
body[ebooktheme="roselexia"] .ebookbox .sdbooktheory h1 {
font-family: eulexia;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="roselexia"] .ebookbox .sdbookexample,
body[ebooktheme="roselexia"] .ebookbox .sdbooktheory {
position: relative;
background-color: #fffafa;
border: 1px solid #f99;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="roselexia"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #700;
text-shadow: 2px 2px 2px white;
background: rgb(255,234,234); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,234,234,1) 0%, rgba(255,163,163,1) 50%, rgba(255,130,130,1) 51%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,234,234,1)), color-stop(50%,rgba(255,163,163,1)), color-stop(51%,rgba(255,130,130,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaea', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="roselexia"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
text-shadow: 2px 2px 2px white;
background: rgb(255,170,170); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,170,170,1) 0%, rgba(255,232,232,1) 13%, rgba(255,255,255,1) 41%, rgba(255,255,255,1) 63%, rgba(255,232,232,1) 83%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,170,170,1)), color-stop(13%,rgba(255,232,232,1)), color-stop(41%,rgba(255,255,255,1)), color-stop(63%,rgba(255,255,255,1)), color-stop(83%,rgba(255,232,232,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffaaaa', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="roselexia"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[rose.png]]) top right no-repeat;
width: 60px;
height: 67px;
position: absolute;
right: -10px;
top: -15px;
content: " ";
}
body[ebooktheme="roselexia"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="roselexia"] .ebookbox .ebookimage {
/* float:right; */
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="roselexia"] .ebookimage .imgcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="roselexia"] .functiongraph .graphcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="roselexia"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="roselexia"] #rightmenu .ebookshelfcontainer {
border: 4px solid #aa0000;
}
body[ebooktheme="roselexia"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="roselexia"] #rightmenu .ebookshelfcontainer h1 {
color: #a00;
border-bottom: 3px solid #a00;
}
body[ebooktheme="roselexia"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_pink.png]]) left top no-repeat;
}
body[ebooktheme="roselexia"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_pink.png]]) right top no-repeat;
}
body[ebooktheme="roselexia"] .ebookshelf_apps ul.applist {
background-color: #a00;
}
body[ebooktheme="roselexia"] .ui-widget.ui-button:not(.ui-state-active),
body[ebooktheme="roselexia"] .ui-widget h3,
body[ebooktheme="roselexia"] .ui-slider a.ui-slider-handle {
font-family: eulexia;
border-color: rgba(255,170,170,1);
background: rgb(252,236,252); /* Old browsers */
background: -moz-linear-gradient(top, rgba(252,236,252,1) 0%, rgba(255,163,163,1) 50%, rgba(255,130,130,1) 51%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(252,236,252,1)), color-stop(50%,rgba(255,163,163,1)), color-stop(51%,rgba(255,130,130,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcecfc', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="roselexia"] .ui-widget h3.ui-state-active {background: #FCE0EE none left top no-repeat;}
body[ebooktheme="roselexia"] .ui-accordion-content,
body[ebooktheme="roselexia"] .ui-widget-content {
background: #FCF3F8 none left top no-repeat;
}
/*}}}*/
!themeid
rosy
!name
Rosy
!author
Pesasa
!css
/*{{{*/
/*body[ebooktheme="rosy"] .bookpage {max-width: 55em;}*/
body[ebooktheme="rosy"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="rosy"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="rosy"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="rosy"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="rosy"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="rosy"] #pageTwoWrapper #pageTwoNavi
{background-color: #ffb1b1;}
body[ebooktheme="rosy"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fee; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="rosy"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="rosy"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="rosy"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="rosy"] #contentWrapper .header {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="rosy"] .bookpage h1.ebooktitle {color: #a00; border-bottom: 2px solid #a00;}
body[ebooktheme="rosy"] .ebookbox .sdbookexample h1,
body[ebooktheme="rosy"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="rosy"] .ebookbox .sdbookexample,
body[ebooktheme="rosy"] .ebookbox .sdbooktheory {
position: relative;
background-color: #fffafa;
border: 1px solid #f99;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="rosy"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #700;
text-shadow: 2px 2px 2px white;
background: rgb(255,234,234); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,234,234,1) 0%, rgba(255,163,163,1) 50%, rgba(255,130,130,1) 51%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,234,234,1)), color-stop(50%,rgba(255,163,163,1)), color-stop(51%,rgba(255,130,130,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,234,234,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffeaea', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="rosy"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
text-shadow: 2px 2px 2px white;
background: rgb(255,170,170); /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,170,170,1) 0%, rgba(255,232,232,1) 13%, rgba(255,255,255,1) 41%, rgba(255,255,255,1) 63%, rgba(255,232,232,1) 83%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,170,170,1)), color-stop(13%,rgba(255,232,232,1)), color-stop(41%,rgba(255,255,255,1)), color-stop(63%,rgba(255,255,255,1)), color-stop(83%,rgba(255,232,232,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,170,170,1) 0%,rgba(255,232,232,1) 13%,rgba(255,255,255,1) 41%,rgba(255,255,255,1) 63%,rgba(255,232,232,1) 83%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffaaaa', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="rosy"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[rose.png]]) top right no-repeat;
width: 60px;
height: 67px;
position: absolute;
right: -10px;
top: -15px;
content: " ";
}
body[ebooktheme="rosy"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="rosy"] .ebookbox .ebookimage {
/* float:right; */
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="rosy"] .ebookimage .imgcaption,
body[ebooktheme="rosy"] .functiongraph .graphcaption {
background-color: #faa;
border: 1px solid black;
border-radius: 5px;
}
body[ebooktheme="rosy"] ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #fee;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="rosy"] .geocaption {
background-color: #faa;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="rosy"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="rosy"] #rightmenu .ebookshelfcontainer {
border: 4px solid #aa0000;
}
body[ebooktheme="rosy"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="rosy"] #rightmenu .ebookshelfcontainer h1 {
color: #a00;
border-bottom: 3px solid #a00;
}
body[ebooktheme="rosy"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_pink.png]]) left top no-repeat;
}
body[ebooktheme="rosy"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_pink.png]]) right top no-repeat;
}
body[ebooktheme="rosy"] .ebookshelf_apps ul.applist {
background-color: #a00;
}
body[ebooktheme="rosy"] .ebook-button,
body[ebooktheme="rosy"] .ui-widget.ui-button,
body[ebooktheme="rosy"] .ui-widget h3,
body[ebooktheme="rosy"] .ui-slider a.ui-slider-handle {
border-color: rgba(255,170,170,1);
background: rgb(252,236,252); /* Old browsers */
background: -moz-linear-gradient(top, rgba(252,236,252,1) 0%, rgba(255,163,163,1) 50%, rgba(255,130,130,1) 51%, rgba(255,170,170,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(252,236,252,1)), color-stop(50%,rgba(255,163,163,1)), color-stop(51%,rgba(255,130,130,1)), color-stop(100%,rgba(255,170,170,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(252,236,252,1) 0%,rgba(255,163,163,1) 50%,rgba(255,130,130,1) 51%,rgba(255,170,170,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcecfc', endColorstr='#ffaaaa',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="rosy"] .ui-widget h3.ui-state-active {background: #FCE0EE none left top no-repeat;}
body[ebooktheme="rosy"] .ui-accordion-content,
body[ebooktheme="rosy"] .ui-widget-content {
background: #FCF3F8 none left top no-repeat;
}
/*}}}*/
!themeid
skulls
!name
Skulls
!author
Pesasa
!css
/*{{{*/
body[ebooktheme="skulls"] .bookpage {max-width: 55em;}
body[ebooktheme="skulls"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="skulls"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="skulls"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="skulls"] #displayArea {border-image:none; -moz-border-image:none; background-color: white; left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="skulls"] #sidePage {border-image: none; -moz-border-image: none; background-color: white; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="skulls"] #mainMenu {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="skulls"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="skulls"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(0,0,0,1);}
body[ebooktheme="skulls"] #contentWrapper .header {background-color: rgba(0,0,0,0.85);}
body[ebooktheme="skulls"] .bookpage h1.ebooktitle {color: #black; border-bottom: 2px solid black;}
body[ebooktheme="skulls"] .ebookbox .sdbookexample h1,
body[ebooktheme="skulls"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="skulls"] .ebookbox .sdbooktheory {
position: relative;
background-color: white;
border: 1px solid black;
box-shadow: 3px 3px 5px black;;
margin: 0.2em 2em;
clear: both;
}
body[ebooktheme="skulls"] .ebookbox .sdbookexample {
position: relative;
background-color: white;
border: none;
box-shadow: none;
margin: 0.2em 2em;
clear: both;
}
body[ebooktheme="skulls"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: white;
text-shadow: 1px 1px 1px #eee;
background: rgb(76,76,76); /* Old browsers */
background: -moz-linear-gradient(top, rgba(76,76,76,1) 0%, rgba(89,89,89,1) 12%, rgba(102,102,102,1) 25%, rgba(71,71,71,1) 39%, rgba(44,44,44,1) 50%, rgba(0,0,0,1) 51%, rgba(17,17,17,1) 60%, rgba(43,43,43,1) 76%, rgba(28,28,28,1) 91%, rgba(19,19,19,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(76,76,76,1)), color-stop(12%,rgba(89,89,89,1)), color-stop(25%,rgba(102,102,102,1)), color-stop(39%,rgba(71,71,71,1)), color-stop(50%,rgba(44,44,44,1)), color-stop(51%,rgba(0,0,0,1)), color-stop(60%,rgba(17,17,17,1)), color-stop(76%,rgba(43,43,43,1)), color-stop(91%,rgba(28,28,28,1)), color-stop(100%,rgba(19,19,19,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(76,76,76,1) 0%,rgba(89,89,89,1) 12%,rgba(102,102,102,1) 25%,rgba(71,71,71,1) 39%,rgba(44,44,44,1) 50%,rgba(0,0,0,1) 51%,rgba(17,17,17,1) 60%,rgba(43,43,43,1) 76%,rgba(28,28,28,1) 91%,rgba(19,19,19,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="skulls"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 1px 1px 1px #eee;
}
body[ebooktheme="skulls"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[skull_hat.png]]) top right no-repeat;
width: 60px;
height: 71px;
position: absolute;
right: -27px;
top: -36px;
content: " ";
}
body[ebooktheme="skulls"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="skulls"] .ebookbox .ebookimage {
float:right;
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="skulls"] .ebookimage .imgcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="skulls"] .functiongraph .graphcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="skulls"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="skulls"] #rightmenu .ebookshelfcontainer {
border: 4px solid black;
}
body[ebooktheme="skulls"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="skulls"] #rightmenu .ebookshelfcontainer h1 {
color: black;
border-bottom: 3px solid black;
}
body[ebooktheme="skulls"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_black.png]]) left top no-repeat;
}
body[ebooktheme="skulls"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_black.png]]) right top no-repeat;
}
body[ebooktheme="skulls"] .ebookshelf_apps ul.applist {
background-color: black;
}
/*}}}*/
!themeid
sportlexia
!name
Sportlexia
!author
Pesasa
!css
/*{{{*/
@font-face {
font-family: 'eulexia';
src: url([[eulexia.ttf]]) format('truetype');
font-weight: normal;
font-style: normal;
}
body[ebooktheme="sportlexia"] .bookpage {font-family: eulexia;}
body[ebooktheme="sportlexia"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="sportlexia"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="sportlexia"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="sportlexia"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="sportlexia"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="sportlexia"] #pageTwoWrapper #pageTwoNavi
{background-color: #B2C27E;}
body[ebooktheme="sportlexia"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fee; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="sportlexia"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="sportlexia"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="sportlexia"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="sportlexia"] #contentWrapper .header {background-color: #004000;}
body[ebooktheme="sportlexia"] .bookpage h1.ebooktitle {color: black; border-bottom: 2px solid black; font-family: eulexia;}
body[ebooktheme="sportlexia"] .ui-widget {font-family: eulexia;}
body[ebooktheme="sportlexia"] .ebookbox .sdbookexample h1,
body[ebooktheme="sportlexia"] .ebookbox .sdbooktheory h1 {
font-family: eulexia;
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="sportlexia"] .ebookbox .sdbookexample {
position: relative;
background-color: #F6FCFF;
border: 1px solid #A4DCFF;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="sportlexia"] .ebookbox .sdbooktheory {
position: relative;
background-color: #FEFFF7;
border: 1px solid #75AC04;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="sportlexia"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 2px 2px 2px white;
background: rgb(201,222,150); /* Old browsers */
background: -moz-linear-gradient(top, rgba(201,222,150,1) 0%, rgba(138,182,107,1) 44%, rgba(57,130,53,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(201,222,150,1)), color-stop(44%,rgba(138,182,107,1)), color-stop(100%,rgba(57,130,53,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c9de96', endColorstr='#398235',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sportlexia"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 2px 2px 2px white;
background: rgb(240,249,255); /* Old browsers */
background: -moz-linear-gradient(top, rgba(240,249,255,1) 0%, rgba(203,235,255,1) 47%, rgba(161,219,255,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(240,249,255,1)), color-stop(47%,rgba(203,235,255,1)), color-stop(100%,rgba(161,219,255,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f0f9ff', endColorstr='#a1dbff',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sportlexia"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[ThemeStyle_Sportlexia##sportlexia-3.png]]) top right no-repeat;
width: 60px;
height: 70px;
position: absolute;
right: -15px;
top: -35px;
content: " ";
}
body[ebooktheme="sportlexia"] .ebookbox .sdbookexample h1:after {
background: transparent url([[ThemeStyle_Sportlexia##sportlexia-1.png]]) top right no-repeat;
width: 89px;
height: 60px;
position: absolute;
right: -45px;
top: -25px;
content: " ";
}
body[ebooktheme="sportlexia"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="sportlexia"] .ebookbox .ebookimage {
/* float:right; */
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="sportlexia"] .ebookimage .imgcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="sportlexia"] .functiongraph .graphcaption {
border: 1px solid #900;
background-color: white;
}
body[ebooktheme="sportlexia"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="sportlexia"] #rightmenu .ebookshelfcontainer {
border: 4px solid #004000;
}
body[ebooktheme="sportlexia"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="sportlexia"] #rightmenu .ebookshelfcontainer h1 {
color: #004000;
border-bottom: 3px solid #004000;
}
body[ebooktheme="sportlexia"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_darkgreen.png]]) left top no-repeat;
}
body[ebooktheme="sportlexia"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_darkgreen.png]]) right top no-repeat;
}
body[ebooktheme="sportlexia"] .ebookshelf_apps ul.applist {
background-color: #004000;
}
body[ebooktheme="sportlexia"] .ui-widget.ui-button:not(.ui-state-active),
body[ebooktheme="sportlexia"] .ui-widget h3,
body[ebooktheme="sportlexia"] .ui-slider a.ui-slider-handle {
font-family: eulexia;
color: black;
border-color: rgba(70,128,70,1);
background: rgb(254,254,253); /* Old browsers */
background: -moz-linear-gradient(top, rgba(254,254,253,1) 0%, rgba(220,227,196,1) 42%, rgba(174,191,118,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,254,253,1)), color-stop(42%,rgba(220,227,196,1)), color-stop(100%,rgba(174,191,118,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefefd', endColorstr='#aebf76',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sportlexia"] .ui-widget h3 a {
color: black;
}
body[ebooktheme="sportlexia"] .ui-widget h3.ui-state-active {
background: #A9DEFF none left top no-repeat;
}
body[ebooktheme="sportlexia"] .ui-accordion-content,
body[ebooktheme="sportlexia"] .ui-widget-content {
background: #EDF8FF none left top no-repeat;
}
body[ebooktheme="sportlexia"] .assignmentLevel0 > h2:before {
content: "\0272a";
color: #ff8000;
text-shadow: 0px 0px 2px black;
}
body[ebooktheme="sportlexia"] .assignmentLevel1 > h2:before {
content: "\0272a\0272a";
color: #c3c3c3;
text-shadow: 0px 0px 2px black;
}
body[ebooktheme="sportlexia"] .assignmentLevel2 > h2:before {
content: "\0272a\0272a\0272a";
color: gold;
text-shadow: 0px 0px 2px black;
}
/*}}}*/
!sportlexia-3.png
data:image/png;base64,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
!sportlexia-1.png
data:image/png;base64,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
!themeid
sports
!name
Sports
!author
Pesasa
!css
/*{{{*/
/*body[ebooktheme="sports"] .bookpage {max-width: 55em;}*/
body[ebooktheme="sports"] .bookpage > span[tiddler] {display: block; margin-left: 0.6em;}
body[ebooktheme="sports"] .bookpage .ebooktoc {margin-top: -3em;}
body[ebooktheme="sports"] {border-image:none; -moz-border-image:none; background: #555 none;}
body[ebooktheme="sports"] #displayArea {border-image:none; -moz-border-image:none; background-color: #fee;left: 0.8em; padding-top: 0.3em;}
body[ebooktheme="sports"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="sports"] #pageTwoWrapper #pageTwoNavi
{background-color: #B2C27E;}
body[ebooktheme="sports"] #sidePage {border-image: none; -moz-border-image: none; background-color: #fee; border-width: 0; padding-top: 1.4em;}
body[ebooktheme="sports"] #mainMenu {background-color: rgba(255,150,150,0.85);}
body[ebooktheme="sports"] #mainMenu.menushow {background-color: rgba(255,255,255,0.85);}
body[ebooktheme="sports"] #mainMenu.menushow .ebooktoc h1 {background-color: rgba(255,150,150,1);}
body[ebooktheme="sports"] #contentWrapper .header {background-color: #004000;}
body[ebooktheme="sports"] .bookpage h1.ebooktitle {color: black; border-bottom: 2px solid black;}
body[ebooktheme="sports"] .ebookbox .sdbookexample h1,
body[ebooktheme="sports"] .ebookbox .sdbooktheory h1 {
background-color: transparent;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: #a00;
}
body[ebooktheme="sports"] .ebookbox .sdbookexample {
position: relative;
background-color: #F6FCFF;
border: 1px solid #A4DCFF;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="sports"] .ebookbox .sdbooktheory {
position: relative;
background-color: #FEFFF7;
border: 1px solid #75AC04;
box-shadow: none;
margin: 0.2em 2em;
}
body[ebooktheme="sports"] .ebookbox .sdbooktheory h1 {
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 2px 2px 2px white;
background: rgb(201,222,150); /* Old browsers */
background: -moz-linear-gradient(top, rgba(201,222,150,1) 0%, rgba(138,182,107,1) 44%, rgba(57,130,53,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(201,222,150,1)), color-stop(44%,rgba(138,182,107,1)), color-stop(100%,rgba(57,130,53,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(201,222,150,1) 0%,rgba(138,182,107,1) 44%,rgba(57,130,53,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c9de96', endColorstr='#398235',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sports"] .ebookbox .sdbookexample h1 {
position: relative;
background-color: #faa;
border: none;
text-align: left;
margin-bottom: 0.5em;
color: black;
text-shadow: 2px 2px 2px white;
background: rgb(240,249,255); /* Old browsers */
background: -moz-linear-gradient(top, rgba(240,249,255,1) 0%, rgba(203,235,255,1) 47%, rgba(161,219,255,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(240,249,255,1)), color-stop(47%,rgba(203,235,255,1)), color-stop(100%,rgba(161,219,255,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f0f9ff', endColorstr='#a1dbff',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sports"] .ebookbox .sdbooktheory h1:after {
background: transparent url([[ThemeStyle_Sports##sports-3.png]]) top right no-repeat;
width: 60px;
height: 70px;
position: absolute;
right: -15px;
top: -35px;
content: " ";
}
body[ebooktheme="sports"] .ebookbox .sdbookexample h1:after {
background: transparent url([[ThemeStyle_Sports##sports-1.png]]) top right no-repeat;
width: 89px;
height: 60px;
position: absolute;
right: -45px;
top: -25px;
content: " ";
}
body[ebooktheme="sports"] .ebookbox {
margin-left: 0;
}
body[ebooktheme="sports"] .ebookbox .ebookimage {
/* float:right; */
min-width: 50%;
clear: both;
border: none;
}
body[ebooktheme="sports"] .ebookimage .imgcaption,
body[ebooktheme="sports"] .functiongraph .graphcaption {
background-color: #d7f0ff;
border: 1px solid black;
border-radius: 5px;
}
body[ebooktheme="sports"] ul.jessiebuttons {
border: 1px solid black;
border-top: none;
background-color: #edf8ff;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="sports"] .geocaption {
background-color: #d7f0ff;
border-radius: 0 0 0.6em 0.6em;
padding: 0.5em 0.8em;
}
body[ebooktheme="sports"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="sports"] #rightmenu .ebookshelfcontainer {
border: 4px solid #004000;
}
body[ebooktheme="sports"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="sports"] #rightmenu .ebookshelfcontainer h1 {
color: #004000;
border-bottom: 3px solid #004000;
}
body[ebooktheme="sports"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url([[bookshelf_line_left_darkgreen.png]]) left top no-repeat;
}
body[ebooktheme="sports"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url([[bookshelf_line_right_darkgreen.png]]) right top no-repeat;
}
body[ebooktheme="sports"] .ebookshelf_apps ul.applist {
background-color: #004000;
}
body[ebooktheme="sports"] .ebook-button,
body[ebooktheme="sports"] .ui-widget.ui-button,
body[ebooktheme="sports"] .ui-widget h3,
body[ebooktheme="sports"] .ui-slider a.ui-slider-handle {
color: black;
border-color: rgba(70,128,70,1);
background: rgb(254,254,253); /* Old browsers */
background: -moz-linear-gradient(top, rgba(254,254,253,1) 0%, rgba(220,227,196,1) 42%, rgba(174,191,118,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,254,253,1)), color-stop(42%,rgba(220,227,196,1)), color-stop(100%,rgba(174,191,118,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(254,254,253,1) 0%,rgba(220,227,196,1) 42%,rgba(174,191,118,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefefd', endColorstr='#aebf76',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="sports"] .ui-widget h3 a {
color: black;
}
body[ebooktheme="sports"] .ui-widget h3.ui-state-active {
background: #A9DEFF none left top no-repeat;
}
body[ebooktheme="sports"] .ui-accordion-content,
body[ebooktheme="sports"] .ui-widget-content {
background: #EDF8FF none left top no-repeat;
}
body[ebooktheme="sports"] .assignmentLevel0 > h2:before {
content: "\0272a";
color: #ff8000;
text-shadow: 0px 0px 2px black;
}
body[ebooktheme="sports"] .assignmentLevel1 > h2:before {
content: "\0272a\0272a";
color: #c3c3c3;
text-shadow: 0px 0px 2px black;
}
body[ebooktheme="sports"] .assignmentLevel2 > h2:before {
content: "\0272a\0272a\0272a";
color: gold;
text-shadow: 0px 0px 2px black;
}
/*}}}*/
!sports-3.png
data:image/png;base64,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
!sports-1.png
data:image/png;base64,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
!themeid
steel
!name
Steel
!author
Pesasa
!css
/*{{{*/
body[ebooktheme="steel"] {
background-color: rgba(200,215,220,1);
font-family: serif;
}
body[ebooktheme="steel"] #pageOneWrapper #pageOneNavi,
body[ebooktheme="steel"] #pageTwoWrapper #pageTwoNavi
{background-color: #aaa; width: 100%; border-radius: 0; border: none; border-bottom: 1px solid #666; top: 0; padding-top: 1em; margin: 0;
background: rgb(242,245,246); /* Old browsers */
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 4%, rgba(227,234,237,1) 94%, rgba(200,215,220,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(4%,rgba(227,234,237,1)), color-stop(94%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="steel"] #contentWrapper[pageopen] #pageOneWrapper #pageOneNavi,
body[ebooktheme="steel"] #contentWrapper[pageopen] #pageTwoWrapper #pageTwoNavi {
width: 50%; padding: 1em; -moz-box-sizing: border-box;
}
body[ebooktheme="steel"] #contentWrapper[pageopen] #pageOneWrapper #pageOneNavi {
border-right: 1px solid black;
}
body[ebooktheme="steel"] .ui-dialog-titlebar,
body[ebooktheme="steel"] .ebook-button,
body[ebooktheme="steel"] .ui-widget.ui-button,
body[ebooktheme="steel"] .ui-widget > h3,
body[ebooktheme="steel"] .ui-slider a.ui-slider-handle {
color: black;
border-color: rgba(160,180,180,1);
border: 1px solid #999;
box-shadow: -1px -1px 2px rgba(0,0,0,0.3),
1px 1px 2px rgba(255,255,255,0.5),
inset 1px 1px 2px rgba(255,255,255,1),
inset -1px -1px 4px rgba(0,0,0,0.3);
background: rgb(242,245,246); /* Old browsers */
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 4%, rgba(227,234,237,1) 94%, rgba(200,215,220,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(4%,rgba(227,234,237,1)), color-stop(94%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="steel"] .ebook-button:active,
body[ebooktheme="steel"] .ui-widget.ui-button:active,
body[ebooktheme="steel"] .ui-widget > h3:active,
body[ebooktheme="steel"] .ui-slider a.ui-slider-handle:active {
box-shadow: -1px -1px 2px rgba(0,0,0,0.3),
1px 1px 2px rgba(255,255,255,0.5),
inset -1px -1px 2px rgba(255,255,255,1),
inset 1px 1px 4px rgba(0,0,0,0.3);
}
body[ebooktheme="steel"] h1.extratitle,
body[ebooktheme="steel"] .ebookbox .sdbookexample h1 {
text-shadow: -1px -1px 1px rgba(0,0,0,0.2), 1px 1px 1px rgba(255,255,255,1);
box-shadow: inset -2px -2px 4px rgba(0,0,0,0.5), inset 2px 2px 4px rgba(255,255,255,0.5);
border-bottom: 2px solid red;
background: rgb(242,245,246); /* Old browsers */
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 4%, rgba(227,234,237,1) 94%, rgba(200,215,220,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(4%,rgba(227,234,237,1)), color-stop(94%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="steel"] div.extraboxclose {
border-radius: 50%;
font-size: 1em;
line-height: 1em;
font-weight: bold;
vertical-align: middle;
display: inline-block;
margin-top: 0.1em;
margin-right: 0.4em;
box-shadow: inset 1px 1px 4px rgba(255,255,255,1), inset -1px -1px 4px rgba(0,0,0,0.5);
text-shadow: -1px -1px 1px rgba(0,0,0,0.7);
}
body[ebooktheme="steel"] .ebookbox .sdbooktheory h1 {
text-shadow: -1px -1px 1px rgba(0,0,0,0.2), 1px 1px 1px rgba(255,255,255,1);
background: transparent;
border-bottom: none;
}
body[ebooktheme="steel"] .ebookbox .sdbookexample,
body[ebooktheme="steel"] .ebookbox .sdbooktheory {
background-color: transparent;
border: 1px solid rgba(160,180,180,1);
box-shadow: none;
margin-left: 0;
margin-right: 0;
}
body[ebooktheme="steel"] .ebookbox .sdbooktheory {
border: 1px solid red;
box-shadow: 0 0 4px red;
background: rgb(242,245,246); /* Old browsers */
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 4%, rgba(227,234,237,1) 94%, rgba(200,215,220,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(4%,rgba(227,234,237,1)), color-stop(94%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="steel"] .ebookbox .sdbooktheory .theorytable {
background-color: white;
}
body[ebooktheme="steel"] .ebookbox .sdbooktheory .value_table {
background-color: transparent;
border-color: transparent;
}
body[ebooktheme="steel"] .ui-widget-content {
background: #fafafa;
}
body[ebooktheme="steel"] .ebookimage .imgcaption,
body[ebooktheme="steel"] .functiongraph .graphcaption {
border: none;
border-top: 2px solid red;
background-color: white;
text-align: left;
}
body[ebooktheme="steel"] ul.jessiebuttons {
border: 1px solid black;
border-top: 1px solid red;
background-color: #eee;
border-radius: 0 0 0.5em 0.5em;
margin: 0 -2px 0 0;
}
body[ebooktheme="steel"] .geocaption {
background-color: white;
border-radius: 0 0 0.6em 0.6em;
border-top: 1px solid red;
padding: 0.5em 0.8em;
}
body[ebooktheme="steel"] #leftmenu .ebookshelfcontainer,
body[ebooktheme="steel"] #rightmenu .ebookshelfcontainer {
border: 4px solid black;
}
body[ebooktheme="steel"] #bottomleftmenu .teacherselection,
body[ebooktheme="steel"] #bottomrightmenu .booksettingsselection {
border: 4px solid black;
border-top: 8px solid black;
}
body[ebooktheme="steel"] #leftmenu .ebookshelfcontainer h1,
body[ebooktheme="steel"] #rightmenu .ebookshelfcontainer h1 {
color: black;
border-bottom: 3px solid black;
}
body[ebooktheme="steel"] #leftmenu.menuopen .ebookshelfwrapper {
left: 50px;
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG4AAABkCAYAAABnwAWdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpQAACKUBTTjBigAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABmJSURBVHic7X1bcFvXleU659wHXgQIQi/Aejiy5AegpDOKx3JNxYrsMFZlutM/jtnRjLvbH4njmalOPHH6Y2qmSmRqUnLlIzUfXWNLpjoOE49bZmJVR7bHVrM7cittdaYt5yWwrMjtuCgblCVDIEECuK9z9nzgXgSkQIqUAIqSuapuiQKBew6x7z53rb3P3pcREVZw/YFf6wms4MqgXe4NjDE21+9oxV2vGVoartlY89lmtlFXDLl0YLO/68AYwesDAwMN4+Tz+cbPuVyu8cG9e/eS/1n4n10xYIcxw3DNRgsMls/nWS6Xm3O5zOfzFBhx79691OyEKwbsHC4hJ4HR9u3btxEAz+VyLJ1OMwC8WCyKnp4eUSwWRbFYFAB4MpnkAHg2m2UDAwOsv7+/cTHMd39cwdWhcY9jjLHAaPl8nnHOE9/61rf+2wMPPPAYAIrH4wwAGxsbY6ZpIhaLUTweJwBULBapVCopAJTNZmlgYABERIyx4LwrntdmMCKaYTT/dZ5Op9mjjz56nDH24T333PPwjh077EgkwkKhEAOAUqmEcDhMAFRwFItFsm1bZTKZ4HX09/cTsLJsthuXLJXZbJYVCgV26tQpruv695RSf3j8+PGXf/rTn641DEOfnJw0lFIG59wAYAAwQqGQXq1W9VQqJTKZjPDPy/P5fGPpXFk224tLDDc6OsoymQxLpVLs3nvvfQHAlFLq3548efKVF154YWs0GjUcxzFN0zRd1zUBGJZlmZFIRK/VajoALR6PC/j3x3w+zwYGBlaM12bMMFxA94vFIgPA77vvPsswjGEAUErd8uabbx45dOjQpwCEPM8Lh0KhkOd5YU3TTF3XzUQiYViWpbuuqwHQisWiSCaTDeKyYrz2oWG44P5WKBRYKpVi0WiUERFPp9PPBu9RSq06derUc88991yvpmlhIoowxiJEFHFdN1ypVEKhUMiUUhoANNM0tUwmI0ZGRlaM12bM8LgHH3wQn/rUpwAAlUqFERF/5JFH8pqm/SZ4DxFFTp8+/VdDQ0N9SqmoECIqpYxKKaOMsQiAkOM4JgBj1apVWjQaFZlMRpRKpUuMt2LAK8ecQeZwOMxs22aoa7W/mfVr8c477/z3wcHBrwKIAYgJIaKapkUBRIQQYQAhy7LMSqWiA9DGx8fF6OioAMAD4wErWu9KMUMO9PX18d7eXj4+Pi7C4bAupTQqlUro7NmzqR/84AcniCgy+wSrV68++uUvf/mvQqGQRUQ2AAuAJYSoSSltx3Hsrq4ux7Ztd3JyUiYSCYnfS4gVuXCFuMTjTp48ecmbNm/eXI3FYq+0OsGFCxfuf/LJJ/vL5fJqAHHGWBeAmOM4MQCRSCQSsm3bBGCsW7euwTjRJBeAFc9bLDjw+6u9OXBcq9Voamqq8cbbb7/9hblOMjExsX3//v3/s1AorCeiBIC4rusxznnU87yo53lhXdfNiYkJI2CcaJILK1pv8Wh4XPCdZTIZ6unpoWg0SqZpkq7rBABf+MIXThmG8a9znWh6evpjQ0ND3zp9+vRWxlhCKZVQSnUBiBmGEXFdN2yaZoNxokkurGi9xaNV5IQuXrxIlUplRjhLKUWZTOZv5zuZZVmrf/SjH/2PN9544w8YYwn/6FJKdUkpo0KIsFIqBMCo1Wp6KpUS27Zt4ytab/GYwe6aCUqlUtE++OADIxwOmwAinPPo2NhY5uDBgy8SkTHfSYUQzs6dO/96165d/0xEUwCmm44qAMu2bTuRSDgffviht3HjRs80TZVMJtXo6CgF6aEVwjI3Gh4XRPNzuRyNj49TuVwmIlIAlKZpUikl169fP5lMJl+73EmllMaxY8ceOXLkyOeVUknGWAJAnHPehbp8iHDOQ5ZlmbFYTLdtWxsfH1/ReotASx2XzWYJgFq9erUCoDzPk57nSQDeHXfc8eJCTkxE/I033viTQ4cO/QkRJQF0K6USnPOuZrEOwFjReovHJVsXALDZy6UQIhQOhyNSyi7OeeLb3/72s7Ztb1joIBs2bHjjoYceesY0zRKAspRySggxBaDqum4tEolYnPMVrbcIXOJxrZZLwzAkY8wD4Cml3PXr1//fxQxy9uzZOwcHB782PT29FkC3ECIBIA4gFgqFIq7rhgOtp+v6itZbAFoulXv37qVguVRKKdM0ped5UgjhSindXbt2vcIYcxcz0IULF249cODA4+fPn98IoDu47xFRDH6YzHEcUwhhuK57SWpoRevNRKs9J8QYw+joKBUKBZJSKtu2JQBPSunquu5s2rTpw2Qy+c+LHaxcLt/0ve9975tvv/32bUSUZIwliCgupeySUkYNw2hovXK5rGNF682JeXcyZzIZ8jxPAWgYTynlAnAWSlJmo1arJQ8dOvTYL37xi38TkBZN0+IAYovVeh9lA7YiJ43f9fX18VwuJ1CPdBgAQkKIKBHFlVLJffv2/dC27fSVDCyEcHfu3PnsZz7zmX9ijE1KKcuc80DzXaL1YrGYTKfTcrbWAz6apGVOjwtICnx2V61WpW3bUkrpAnA453Ymk3n1SgeWUurHjh378xdffPHzgedhltaLRqMNrReNRkUrrefP9SPneXN6XBBJGR4e5qOjo2J6elpPpVKGbdth1L/Y+O9+97vNQ0ND/4eIxNVM4rbbbvvpnj17ngcwAaDheY7jVDVNqzmOYyulnFAo5ALw0BSK+6h63pweF5CU4eFhpNPpGSRFCOECcG655ZYPuru7/9/VTuL06dP3Dg4OfsV13VXwhbpSqitIzEYikVBXV5dhmqYOQJucnGzIhb6+Pv5RlAuXLbMKNF0zSZFSup7nuUop+7bbbnupHRN57733tu/fv//rU1NTadSXzW74Wi/Y09Iqr/dRlQvzkZPGe4LlEk0kBf5ySUQ9+/bte9ZxnDXtmFA8Hh/fs2fP/06n02OMsUkimuKcTymlKkKIGufcmp6edkzTdAF4xWJR2ratSqWSyuVyH5kA9WU9LtB08O8p4XBY2rYtXdd1ATiMMSuTyRxt14TK5XJ6aGjo8TNnztzeSusFeT3ULyAtlUoJ0zQ/cqmhBVekBpGUCxcuqHg87qFOEhzOuX3PPfe8zBiT7ZpUrVbrfv755x87efLk9mat58dKo0KIsKZpJnytZ5qmtm3bNt5qG+CNasDLVqQGS05fXx/r7e2lt956S01MTCghhCeEcInI2bp1ayGRSJycmJi4q10Tc103/NJLL/2nqampZ3ft2vUzxhjXNI0rpZiUkhMR1zSNJRIJ5jgOs20bmUxGlkolZLNZdaMXnizI45oDzx/72MdUOByWsVjMsyzLY4w5rus6t95668vtnpxSSnvttdf+7Cc/+ckfNqeGhBANxhlEWZpTQ6VSieMGTw0thJxcoungkxTHccKGYUQBxKWUPU888cTfuK6b6sREb7311mN79ux5nnM+QUSTgdZjjFWllPNqPeDGSw0tyONmB57hfyGxWMzTNM0F4AghrHQ6/Xedmuhvf/vbXYODg4/Ytr2KMZZUSjWyC57nRSORSCgUCpkAjGq1qt/oqaFFt8vIZDJULBYpGo1Kx3EkAM/zPJdzbt99990vAejYFf3+++9/cv/+/V+fnJxcp5RKKqUSnufFGWMxz/Oi8Le/RyIR/UZPDS3KcHv37qV8Pk/btm1TQggVCoUkY6zhddls9r1EIvGLDs0VAFAsFm95+umnv3nu3LlNjLEk5zwhhOiCn10Ih8MhXddv+NTQgg03ezORpmnKsizpuq7UNM1ljDlSSnvLli1tJymzMTU1tW5oaOibb7311u1KqUaAWtf1WKD1gsIT+FrvRtsGeEWdhYK9l6jf6zzGmBdkDe6///6f6bo+0dZZtoBlWYnh4eHH3nzzze2B8ZRSiUDrAYgEWi8UCuljY2Patm3b+I2yk2xRhiMi6u/vp9kkpXm51DStum7dupGOzHYWPM8Lvfzyy48eO3ZsZ2A8TdPiSqkuznnUL1IJKaWM+bYBAtcfabniXl6tSAoROUIIe8eOHR0lKc1QSmnHjx//0yNHjvxRYDx/C3yXlHJOrXe9bwNckI6b8YEWO54dxzGklCHXdaOoR/S7v/vd7/6vcrn8Bx2Z9RzYunXrP37pS186pGlaCUA52EUthKgEWu9GKflatMe12vF88eJF5bquRFP8cvPmzS3LsjqJM2fO7Dx48OBXq9XqaviexznvatZ6N8o2wKtqe9i8hc+yLKnruut5nuu6rrN79+5jmqaV2zTPBaNQKHxicHDw66VSKQOfsBDRDaf1rshwRER79+6l5i18oVCoIQ0AONFotLJ27dp/aPN8F4Risbh5cHDw8ffff/9mxliSiBpaj3MeNQwjDCB0PWu9K/a45nq6IDuO+lLpCSFcpZR95513XtEWvnZgenp6ra/17mCMNbQe/I1Inudd11rvqpbKIJKSSqUoHo/LUCjUuM8BcLZv3/5OV1dXvi0zvQJYlhUfHh7++s9//vM7A+MFhSdBdkHTNNO2bfN603pXbLhmkgJABSQFvtcBcIjIvvnmmxdVZ9BueJ4XeuWVV746MjJyb7PxAqFORBHTNM3rTeu1pSfz7DoD+Msl59zevXv3PwghptsxzpVCKSWOHz/+Hw8fPvzHgfECoX69ar1F67hW5+jr6+PJZJJHo1EtkUjoqG8mivibW7uffPLJvxwfH//CVc+2DdiyZcvPHnrooecATASbkdCk9XRdt6+Hkq+r9rhguZyrzsB1XWf79u3XjKTMxttvv/3pAwcOPDqX1iOi60LrtWWpbCYpABrLped5rhDCvuuuu87EYrG32jFWO1AoFD7+9NNPP1YqlW4C0O15XjcRxQ3DiAXtPZa71rtqw80mKfDrDAB4mqa5UkqXiOxNmzYteSRlPpRKpZsHBwcff++99zYLIbqJKEFEcfjtPZa71mvrAyNakRTDMBwAzu7du/9eCFFt53hXi+np6TVDQ0OPj46O5gKhDqBBWjzPa5R8YZlpvbYYLoiktKozCPJ08Xi8vHr16st2bFhq2Lbd9eMf//hrJ06cuKtZqOu6HtM0Lep5XhhAaLlpvbZ5XHPgeTZJgR94/uQnP9mWOoN2w/M88+jRo185evTofbOFerABl3O+rPJ67ZAD9RM1pXtmF0N6nhdljMWFEMnvfOc7B6rV6i1tGbQD+MQnPvHyAw888BMimgRQRr1LREUIUYHfGRD1yFAQaLgmJV9t87hWJCUcDjdICgBHSmlv2rTpmkZSLodf//rX//773//+nxFRD3y5EASoAURc1w3rum62KvkKnrsAdN7zOvI0q+Y6g2aSIoSwe3t7/45zbnVi3HbhnXfe+XcHDhz4z5ZlrQkKT1Cvlo0yxpZFe4+2Gm4hJCWVSk2sXr36H9s5bicwPj6e279//2OlUumm5qohxtiM7MJ8Wg/onPHa7nELISkf//jHlyVJmY1SqbRpcHDw8bNnz26GX2zJGLus1lsK43VkqZwrkiKEcF3XdT796U+fCofD73Zi7HajUqms/uEPf/iNU6dObQPQzTm/ROvNzuv19PQ0hHqnoixtN9x8JCVocCOltDdu3LisSUozbNvuOnz48F+cOHFiRyuthznyep2MsnT0UZutSIpSyhVC2J/97GePcs7tTo7fTnieZ7766qtfefXVVz+7kLze2NiYlslkOvbAjMsWNl4JWhVDBvc5z/NcTdOcNWvWXEylUv904cKF+zoxh06AiPjrr7++Z2pqqvuLX/zi3wbFlUopBoABaPwci8UAgGUyGbQotrzqQsuOedxcJCXQdACcXC53XZCU2fjNb37z+WeeeeZhIupplgvwO0TA30lmWdaMYst2el7bIieXnHiOYkjMaiv1xBNPPGNZ1oJ7Xy4nrFu3bvThhx9+OhwOXwBQZoyV4TfWCYVCVc/zbABOtVp1Xdf1mpOyV9sdomMe16oYMujYEGg6KaW9YcOGZZXuWQzOnTuXfeqpp/5rsVhcD6CbiObM681+5kJfXx+/Gs9bkueA9/b2Kszq2BCQlHvvvXfRvS+XEyYmJjYePHjwm+++++6WoE59IXm9XC7Hgq5IV2K8jhpuvkhK0FZq7dq1xZ6enhOdnEenUalUVj377LPfOHXq1DYiSkopZxSetGrlOFvroX53WbABO+5xc5GUoK2UEMLOZrPXJUlphuM4scOHD//F66+/voNzPqNDRCDUAYQ45416vUwmI3p7e6+ItHSMnDQGWCBJ2bdv3w9s2850dDJLAMaYuvvuu3+0e/fuv1dKTXLOJ4OWVgCqmqbVAtICPzWUTqfl+Pg4YRGkpeMeNx9JsSzLU0q5nHP7pptualtbqWsJIuInTpzoGx4efoBzngyaDARJWcuyWsoFNKWGFuJ5S0JOAgRPKw4iKbquuwAc13WdnTt3vszqndZvCOTz+fsDrYcWrRwZY3O2cgzyevMZb0kMF5CUfD5PAUmp1WrScRwZkJTNmzefTyaTV937cjnh3Xff3bF///7/UqvV1jTl9Lo451Fd18PVajWklDJM09QTiYRoNh4AzOd5S+Zxs0lKOByWRORZluURkdPO3pfLCefPn7/jqaee+sb58+fXM8YSnuc1Goc3G8+yLD2RSAj4z2C/HGFZ0qUyeJ5Bc7pH13U3CIN97nOf+7lhGB8s5ZyWApOTkxv8tv23cM67lFJdQojGkklERigU0gFo09PTwrZtPjIy0sgstDrnkhluLpJiGEaj96WmadbVNOhezqhWq6sOHTr0l7/85S9zAGKMsSiAiGEYIc/zTE3TdABaLBYTFy9eFJlMhuVyOQa0XjKX1OMCNJMUxpgXkBSlVNt7Xy4nOI4TO3LkyOPHjh3bQURRxlhYKRUGECIiw3EcHf7TLOEvmXN53ZIarhVJmZiYUPDTPQCC3pf/spTzWkpIKc3XXnvta4cPH74fdUFuAjBs2zYikYhm27ao1WoCAB8fH5/hdc1Yco9rJilB78sg3SOEsAFYW7ZsWTbVPZ0AEfFf/epXX3nmmWf+g+d5BudcNwxDsyxLM01TMMZ4NBplPT09rFAosHw+f8nelY5HTmZjrkiKruumUioipewC0H3+/PmMECIphEgyv9mav8MqyhgLAzAYY40H5aKeyFxyNOVEFWNMUf1hiR4ReQBcIrIZY5ZSqkpEVSKaJqJpKWVZKTWVSqXOcc4n0VSjZ9djgk4kEnELhYIMGoX39/dTMFhHMuDzIcgA9/f3U6FQoEwmo6rVquzu7vb8+KWtaVp1zZo15/0MggPAJqIagC4AUdQLJ01//pp/MQSrx1UbkDE279Xc4mIPXlD+z9I/XP+wichijFUBVABMK6UqnPMKAOKcMwBMSslc12VdXV0QQuDcuXMsk8mw3t5ejI6Ozhh3yQ3XjN7eXjU6OsoikYjknHuO47iGYdicc00ppXHONd/OQP2LcADUUDeaAUAHIHyjsab3XhUWsgrNsfuA/GNGFwoALmPMBmAxxmqMMYsx5qBuVAn/4cHNJ6rVamzDhg0ol1u3irkmhmvek5JMJimTySjLsqRhGC4AwRgTAATnnCml4C8/Lup/eBh1oxlE1GBgWGRapA1/wyUvNf0bHNJnyB4Ruag3NLCIyEL9ArQ55w7qO+CkYRjScRzlOA5Vq1WanJxEIpFoOf418zjGGPr7+ymbzarR0VEWj8dluVz2UH+WQbDxBqh/AUELjioRNerV/IP7S+WSGm42pJTgnBPQ8EZijJGUUnHOJertIQPj2Uopm3NeA2AppWz/oYoSgLIsiyKRCAGgQqFA2Wz2kvGWnJw0Bp5Z3cN6enrE2NiYtmrVKk0pZfhPbzR9Q4VQb19ook5KdCmlJoTgAHhgNCK6pnXZzffGwHD+6qICz0OT93HObd9otpTS1nXdZow5juM0nmKSSqVkPp+n559/XjWne66Zx/kTYLlcjrLZLEqlkorFYlKIxoOxSEqpAEjP8zxN02z4nkZEmqZpAnWjBfc3KKVY0+c7hrpjzI3A8+Avmf7/Fer3MgnA45y7Pvlyg/udH0FqbCjyQ4PB5uIZuKbkJLiCBgYGAID8hCKi0ShqtRo45xSLxYIrVWs6uOu6QgjBOOeMiJiUMtA6HZ/35VYpKSWEEA3y4rou6boeEBAlhJD+suhJKQMC0zj824YCoPL5POVyuWDcxsDX1HDNm0MHBgbU+Pg4T6fT0rZtCofDVK1Wleu60jAMz3Ecoeu6cF1XAOCmaTLP84L7WsPT/PtiR7EYrxZCkBACUkrSNI08zwtWEqXrupyenlamacparSbD4bCcnJyUxWJR2bZNvb29BKD5QU+N815TwwXwiQoAqGQyyUZGRpDJZCgSiSgAcmJiQjDGuGVZPBQKMQC8Uqmwrq4uOI7DADT+XW4wDKPxbftLJhmGQY7jkOu6yjTNoL5CAVCJREIVCgXypVJAdi457zUjJzMm4c+MiDAwMMCy2SwbHR1l6XSajY+PMwA8Ho+zcrnMotEoq1QqLBwOM6Cud67p5BeBcDhMxWIRkUiEotEoVSoVisfjVC6XqVgs0rZt29T4+Dhls1kKjDbXHpRl4XHBkjn7njcyMsJyuRwrFAqUTqdRLpfZ2NgY27p1Ky5evHjdGCxArVZDJBJBT08PnTlzBqlUisrlMvwIEiWTSRoZGQH85RH4PQ+Yfa5l4XHNmO19wev5fJ49+OCDAIDR0dHrzmit4FczYXh4eAZzXEgTgGVnuADNYrp5jnNlhK9XBJ4FzLyXXW573v8HHj0e9pCnSyMAAAAASUVORK5CYII=) left top no-repeat;
}
body[ebooktheme="steel"] #rightmenu.menuopen .ebookshelfwrapper {
right: 50px;
background: transparent url(data:image/png;base64,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) right top no-repeat;
}
body[ebooktheme="steel"] #bottomrightmenu .booksettingsselection #indicatorlights,
body[ebooktheme="steel"] .ebookshelf_apps ul.applist {
border-bottom: 1px solid black;
background: rgb(242,245,246); /* Old browsers */
background: -moz-linear-gradient(top, rgba(242,245,246,1) 0%, rgba(227,234,237,1) 4%, rgba(227,234,237,1) 94%, rgba(200,215,220,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(242,245,246,1)), color-stop(4%,rgba(227,234,237,1)), color-stop(94%,rgba(227,234,237,1)), color-stop(100%,rgba(200,215,220,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* IE10+ */
background: linear-gradient(to bottom, rgba(242,245,246,1) 0%,rgba(227,234,237,1) 4%,rgba(227,234,237,1) 94%,rgba(200,215,220,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f5f6', endColorstr='#c8d7dc',GradientType=0 ); /* IE6-9 */
}
body[ebooktheme="steel"] #bottomrightmenu .booksettingsselection #indicatorlights {
border-radius: 5px 5px 0 0;
}
/*}}}*/
|~ViewToolbar|editTiddler closeOthers closeTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<div class='upPage'><span class='navihead'>Up page: </span><span macro='view uppage link'></span></div>
<div class='prevPage'><span class='navihead'>Previous page: </span><span macro='view prevpage link'></span></div>
<div class='nextPage'><span class='navihead'>Next page: </span><span macro='view nextpage link'></span></div>
<div class='downPage'><span class='navihead'>Down page: </span><span macro='view downpage link'></span></div>
<!--}}}-->
/***
|''Name:''|SdBookJS|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Author tools for mathematics Ebook|
|''Version:''|0.2|
|''Date:''|October 28, 2011|
|''Source:''| |
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
***/
//{{{
config.macros.authortools = {
handler: function(place, macroName, params, wikifier, paramString, tiddler)
{
var $element = jQuery(place);
$element.append('<button class="create_theory_shuffle">Create Theory shuffle</button>');//localize
$element.append('<button class="create_theory">Create Theorybox</button>');//localize
$element.append('<button class="create_example">Create Examplebox</button>');//localize
$element.append('<button class="create_textelement">Create Textelement</button>');//localize
$element.append('<button class="create_subsection">Create Subsection</button>');//localize
$element.find('.create_subsection').button({
icons: {
primary:"ui-icon-gear",
secondary: "ui-icon-circle-plus"
}
}).click(function()
{
var subsection_name = "subsection";
var subsection_number = 0;
while (store.tiddlerExists(subsection_name+"_"+subsection_number)){subsection_number=subsection_number+1;}
var subsection_container = store.createTiddler(subsection_name+"_"+subsection_number);
subsection_container.tags.push("subsection");
subsection_container.tags.push("container");
//subsection_container.tags.push("notFixed"); POISTETTU manuaalieditoinnissa
$element.append('<div class="add_subsection">\n<h1>Add Subsection</h1>\n<span class="tag_insert">Insert tags <input class="tags_input" type="text"/>(separate tags with space) </span><br/><span class="add_elem ebook_title">Ebook title:<input type="text" class="add_ebook_title"/></span><br /></div>');
var $add_dialog = $element.find('.add_subsection');
$add_dialog.dialog({
autoOpen: true,
buttons: {
"Submit":function(){
var Ebook_title = jQuery(this).find('.add_elem.ebook_title input').val();
if (Ebook_title !=""){
subsection_container.text = "!!"+Ebook_title+"\n";
subsection_container.fields.ebooktitle = Ebook_title;
}
var tags_to_insert = jQuery(this).find('.tag_insert input.tags_input').val().split(" ");
for(var i=0;i<tags_to_insert.length;i++){subsection_container.tags.push(tags_to_insert[i]);}
subsection_container.text = "!!"+Ebook_title;
$add_dialog.dialog('destroy');
$element.find('.add_subsection').remove();
saveChanges();
}
},
close: function() {
jQuery( this ).dialog( "close" );
}
});
});
$element.find('.create_textelement').button({
icons: {
primary:"ui-icon-gear",
secondary: "ui-icon-circle-plus"
}
}).click(function()
{
var textelement_name = "textelement";
var textelement_number = 0;
while (store.tiddlerExists(textelement_name+"_"+textelement_number)){textelement_number=textelement_number+1;}
var textelement_container = store.createTiddler(textelement_name+"_"+textelement_number);
textelement_container.tags.push("textelement");
textelement_container.tags.push("container");
textelement_container.tags.push("notFixed");
textelement_container.text = "<<tiddler [["+textelement_name+"_"+textelement_number+"_data]] >>";
var textelement_data = store.createTiddler(textelement_name+"_"+textelement_number+"_data");
textelement_data.tags.push("textelement");
textelement_data.tags.push("data");
$element.append('<div class="add_textelement">\n<h1>Add Text</h1>\n<span class="tag_insert">Insert tags <input class="tags_input" type="text"/>(separate tags with space) </span><br/><span class="add_elem text_elem"><textarea class="add_text_textarea"></textarea></span><br /></div>');
var $add_dialog = $element.find('.add_textelement');
$add_dialog.dialog({
autoOpen: true,
buttons: {
"Submit":function(){
var $add_elemes = jQuery(this).find('.add_elem');
if ($add_elemes.length == 0){alert("Add something!");return false;}
var $current_elem;
for (var i=0;i<$add_elemes.length;i++){
$current_elem = $add_elemes.eq(i);
if ($current_elem.hasClass('text_elem')){
textelement_data.text = textelement_data.text+$current_elem.find('textarea').val()+"\n";
}
}
var tags_to_insert = jQuery(this).find('.tag_insert input.tags_input').val().split(" ");
for(var i=0;i<tags_to_insert.length;i++){textelement_container.tags.push(tags_to_insert[i]);}
$add_dialog.dialog('destroy');
$element.find('.add_textelement').remove();
saveChanges();
}
},
close: function() {
jQuery( this ).dialog( "close" );
}
});
});
$element.find('.create_example').button({
icons: {
primary:"ui-icon-gear",
secondary: "ui-icon-circle-plus"
}
}).click(function()
{
var examplebox_name = "examplebox";
var example_number = 0;
var exaplederiv_number = 0;
var exaplederivs = [];
while (store.tiddlerExists(examplebox_name+"_"+example_number)){example_number=example_number+1;}
var examplebox_container = store.createTiddler(examplebox_name+"_"+example_number);
examplebox_container.tags.push("examplebox");
examplebox_container.tags.push("container");
examplebox_container.tags.push("notFixed");
examplebox_container.text = "<<ebookbox [["+examplebox_name+"_"+example_number+"_data]] example>>";
var examplebox_data = store.createTiddler(examplebox_name+"_"+example_number+"_data");
examplebox_data.tags.push("examplebox");
examplebox_data.tags.push("data");
$element.append('<div class="add_examplebox">\n<h1>Add example box</h1>\n<span class="example_header_elem">examplebox header: <span class="mathquill-textbox"></span></span><br>\n<span class="tag_insert">Insert tags <input class="tags_input" type="text"/>(separate tags with space) </span><br/></div>');
var $add_dialog = $element.find('.add_examplebox');
$add_dialog.find('.mathquill-textbox:not(mathquill-editable)').mathquill('textbox');
$add_dialog.dialog({
autoOpen: true,
buttons: {
"Add text element": function() {
jQuery( this ).append('<span class="add_elem text_elem"><textarea class="add_text_textarea"></textarea></span><br />');
},
"Add (empty) Structured derivation": function() {
jQuery( this ).append('<div class="add_elem sd_elem"><div class="dialog_deriv'+exaplederiv_number+'" style="border:1px solid black;"></div></div><br />');
jQuery(this).find('.dialog_deriv'+exaplederiv_number).append("Here will be empty derivation");
// var place = jQuery(this).find('.dialog_deriv'+exaplederiv_number);
// var editor = new QedEditor("examplesd"+exaplederiv_number, place, 'dialog');
// exaplederivs.push(editor);
// exaplederiv_number++;
},
"Add displaystyle formula": function() {
jQuery( this ).append('\n<span class="displaystyle_formula_head">Displaystyle formula: <span class="add_elem displaystyle_formula"><span class="mathquill-mathbox"></span></span></span><br />');
jQuery(this).find('.mathquill-mathbox').removeClass('mathquill-mathbox').mathquill('editable');
},
"Submit":function(){
var header_text = jQuery(this).find('.example_header_elem .mathquill-editable').mathquill('latex');
if (header_text==""){alert("Add header!");return false;}
var $add_elemes = jQuery(this).find('.add_elem');
if ($add_elemes.length == 0){alert("Add something!");return false;}
examplebox_data.text = "!"+header_text.replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\n";
var $current_elem;
for (var i=0;i<$add_elemes.length;i++){
$current_elem = $add_elemes.eq(i);
if ($current_elem.hasClass('text_elem')){
examplebox_data.text = examplebox_data.text+$current_elem.find('textarea').val()+"\n";
}else if ($current_elem.hasClass('displaystyle_formula')){
examplebox_data.text = examplebox_data.text+"\\["+$current_elem.find('.mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\\]"+"\n";
}else if ($current_elem.hasClass('sd_elem')){
examplebox_data.text = examplebox_data.text+"<<qedderiv examplesd"+exaplederiv_number+" savehere>>"+"\n";
exaplederiv_number++;
}
}
var tags_to_insert = jQuery(this).find('.tag_insert input.tags_input').val().split(" ");
for(var i=0;i<tags_to_insert.length;i++){examplebox_container.tags.push(tags_to_insert[i]);}
$add_dialog.dialog('destroy');
$element.find('.add_examplebox').remove();
saveChanges();
}
},
close: function() {
jQuery( this ).dialog( "close" );
}
});
});
$element.find('.create_theory').button({
icons: {
primary:"ui-icon-gear",
secondary: "ui-icon-circle-plus"
}
}).click(function()
{
var theorybox_name = "theorybox";
var thoery_number=0;
while (store.tiddlerExists(theorybox_name+"_"+thoery_number)){thoery_number=thoery_number+1;}
var theorybox_container = store.createTiddler(theorybox_name+"_"+thoery_number);
theorybox_container.tags.push("theorybox");
theorybox_container.tags.push("container");
theorybox_container.tags.push("notFixed");
theorybox_container.text = "<<ebookbox [["+theorybox_name+"_"+thoery_number+"_data]] theory>>";
var theorybox_data = store.createTiddler(theorybox_name+"_"+thoery_number+"_data");
theorybox_data.tags.push("theorybox");
theorybox_data.tags.push("data");
$element.append('<div class="add_theorybox">\n<h1>Add theory box</h1>\n<span class="theory_header_elem">Theorybox header: <span class="mathquill-textbox"></span></span><br>\n<span class="tag_insert">Insert tags <input class="tags_input" type="text"/>(separate tags with space) </span><br/></div>');
var $add_dialog = $element.find('.add_theorybox');
$add_dialog.find('.mathquill-textbox:not(mathquill-editable)').mathquill('textbox');
$add_dialog.dialog({
autoOpen: true,
buttons: {
"Add text element": function() {
jQuery( this ).append('<span class="add_elem text_elem"><textarea class="add_text_textarea"></textarea></span><br />');
},
"Add displaystyle formula": function() {
jQuery( this ).append('\n<span class="displaystyle_formula_head">Displaystyle formula: <span class="add_elem displaystyle_formula"><span class="mathquill-mathbox"></span></span></span><br />');
jQuery(this).find('.mathquill-mathbox').removeClass('mathquill-mathbox').mathquill('editable');
},
"Submit":function(){
var header_text = jQuery(this).find('.theory_header_elem .mathquill-editable').mathquill('latex');
if (header_text==""){alert("Add header!");return false;}
var $add_elemes = jQuery(this).find('.add_elem');
if ($add_elemes.length == 0){alert("Add something!");return false;}
theorybox_data.text = "!"+header_text.replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\n";
var $current_elem;
for (var i=0;i<$add_elemes.length;i++){
$current_elem = $add_elemes.eq(i);
if ($current_elem.hasClass('text_elem')){theorybox_data.text = theorybox_data.text+$current_elem.find('textarea').val()+"\n";}
if ($current_elem.hasClass('displaystyle_formula')){theorybox_data.text = theorybox_data.text+"\\["+$current_elem.find('.mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\\]"+"\n";}
}
var tags_to_insert = jQuery(this).find('.tag_insert input.tags_input').val().split(" ");
for(var i=0;i<tags_to_insert.length;i++){theorybox_container.tags.push(tags_to_insert[i]);}
$add_dialog.dialog('destroy');
$element.find('.add_theorybox').remove();
saveChanges();
}
},
close: function() {
jQuery( this ).dialog( "close" );
}
});
});
$element.find('.create_theory_shuffle').button({
icons: {
primary:"ui-icon-gear",
secondary: "ui-icon-circle-plus"
}
}).click(function()
{
var shuffle_name = "theory_shuffle";
var shuffle_number=0;
while (store.tiddlerExists(shuffle_name+shuffle_number)){shuffle_number=shuffle_number+1;}
var theory_shuffle_container = store.createTiddler(shuffle_name+shuffle_number);
theory_shuffle_container.tags.push("theory_shuffle");
theory_shuffle_container.tags.push("container");
theory_shuffle_container.text = "<<theoryshuffle "+shuffle_name+shuffle_number+"_data>>";
var theory_shuffle_data = store.createTiddler(shuffle_name+shuffle_number+"_data");
theory_shuffle_data.tags.push("theory_shuffle");
theory_shuffle_data.tags.push("data");
$element.append('<div class="add_theoryshuffle">\n<h1>Add theory shuffle</h1>\n<div class="add_elems_count">\n<form> \n<span class="add_elem_count_q">How many element to shuffle?<select name="elem_count" class="shuffle_elem_count"><option selected>select...</option>\n <option>2</option>\n <option>3</option>\n <option>4</option>\n <option>5</option>\n <option>6</option>\n <option>7</option>\n <option>8</option>\n <option>9</option>\n</select></span></form\n</div>\n</div>');
var shuffle_elem_count=0;
var one_shuffle_elem = '<span class="one_shuffle_elem">\n<span class="q_header">Solid:</span>\n<span class="shuffle_solid">\n\t<span class="mathquill-textbox"></span>\n</span>\n<span class="q_header">Sortable:</span>\n<span class="shuffle_sortable">\n<span class="mathquill-textbox"></span>\n</span>\n<span class="q_header">Additional text:</span>\n<span class="shuffle_additional_text">\n<span class="mathquill-textbox"></span>\n</span>\n</span><br/>\n';
var shuffle_posttext_elem = '<span class="shuffle_posttext_elem">Text after sort:<span class="mathquill-textbox"></span></span>\n';
var shuffle_header_elem = '<span class="shuffle_header_elem">Theorybox header<span class="shuffle_header"><span class="mathquill-textbox"></span></span></span><br>\n';
var tag_input_field = '<span class="tag_insert">Insert tags <input class="tags_input" type="text"/>(reparate tags with space) </span><br/>';
$element.find("form").submit(function() {
return false;});
$add_dialog = $element.find('.add_theoryshuffle');
$add_dialog.dialog({
autoOpen: true,
close: function() {
}
});
$add_dialog.find('.shuffle_elem_count').change(function(){
var allowlist = [2,3,4,5,6,7,8,9];
if(allowlist.contains(parseInt(jQuery(this).val()))){
shuffle_elem_count=jQuery(this).val();
$add_dialog.find('.add_elem_count_q').hide();
$add_dialog.find('form').append(tag_input_field);
$add_dialog.find('form').append(shuffle_header_elem);
for(var i=0;i<shuffle_elem_count;i++){
$add_dialog.find('form').append(one_shuffle_elem);
};
$add_dialog.find('form').append(shuffle_posttext_elem);
$add_dialog.find('.mathquill-textbox').mathquill('textbox');
$add_dialog.dialog("option","buttons",{"Submit":function(){
solid_elems = $add_dialog.find('span.shuffle_solid .mathquill-editable');
for(var i=0;i<solid_elems.length;i++){
if(solid_elems.eq(i).mathquill('latex')==""){
alert("fill all solid fields");
return false;
}
};
sortable_elems = $add_dialog.find('span.shuffle_sortable .mathquill-editable');
for(var i=0;i<sortable_elems.length;i++){
if(sortable_elems.eq(i).mathquill('latex')==""){
alert("fill all sortable fields");
return false;
}
};
for(var i=0;i<sortable_elems.length;i++){
for(var j=i+1;j<sortable_elems.length;j++){
if(sortable_elems.eq(i).mathquill('latex')
==sortable_elems.eq(j).mathquill('latex')){
alert("all sortables have to be different!");
return false;
}
}
};
var tags_to_insert = $add_dialog.find('.tag_insert input').val().split(" ");
for(var i=0;i<tags_to_insert.length;i++){theory_shuffle_container.tags.push(tags_to_insert[i]);}
theory_shuffle_data.text="{{theory_shuffle{\n{{theory_shuffle_header{\n";
if ($add_dialog.find('span.shuffle_header .mathquill-editable').mathquill('latex')==""){
theory_shuffle_data.text=theory_shuffle_data.text+"!Theory\n";
}else{
theory_shuffle_data.text=theory_shuffle_data.text+"!"+$add_dialog.find('span.shuffle_header .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\n";
};
theory_shuffle_data.text=theory_shuffle_data.text+"}}}{{theory_shuffle_box{\n{{question_box{\n";
for(var i=0;i<shuffle_elem_count;i++){
theory_shuffle_data.text=theory_shuffle_data.text+"*{{to_middle{"+solid_elems.eq(i).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"}}}\n";
};
theory_shuffle_data.text=theory_shuffle_data.text+"}}}{{answer_box{\n";
add_text_elems = $add_dialog.find('span.shuffle_additional_text .mathquill-editable');
for(var i=0;i<shuffle_elem_count;i++){
theory_shuffle_data.text=theory_shuffle_data.text+"*{{to_middle{ "+sortable_elems.eq(i).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"{{theory_shuffle_add{ "+add_text_elems.eq(i).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"}}}}}}\n";
};
theory_shuffle_data.text=theory_shuffle_data.text+"}}}}}}{{theory_shuffle_text{\n";
theory_shuffle_data.text=theory_shuffle_data.text+$add_dialog.find('span.shuffle_posttext_elem .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)')+"\n";
theory_shuffle_data.text=theory_shuffle_data.text+"}}}{{theory_shuffle_clearer{\n}}}\n}}}\n";
$add_dialog.dialog('destroy');
$element.find('.add_theoryshuffle').remove();
saveChanges();
}});
}else{
alert("invalid input!");
jQuery(this).val("").focus();
}
});
}
);
}
}
//}}}
/***
|Name|EbookSettingsPlugin|
|Source|http://e-math.imped.fi|
|Documentation|http://e-math.imped.fi|
|Version|1.0|
|Author|Petri "pesasa" Salmela|
|License|CC-BY-SA 3.0 (plugin inspired by http://www.TiddlyTools.com/#AttachFilePlugin by Eric Shulman)|
|~CoreVersion|2.1|
|Type|plugin|
|Requires| |
|Description|Plugin for changing settings of math ebook.|
!!!!!Documentation
>see [[EbookSettingsPluginInfo]]
!!!!!Inline interface (live)
>see [[EbookSettings]] (shadow tiddler)
><<tiddler EbookSettings>>
!!!!!Revisions
<<<
2012.03.21 0.0.1 First version
<<<
<<<
20130917.15.20 ''add''
* Added checkbox for Eulexia-font.
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.EbookSettingsPlugin= {major: 0, minor: 0, revision: 1, date: new Date(2012,3,21)};
// shadow tiddler
config.shadowTiddlers.EbookSettings="<<ebooksettings inline>>";
// Set current language
config.options.txtLang = DataTiddler.getData(Emathbook.config.userdatatiddler, 'lang', 'fi');
jQuery('body').attr('lang', config.options.txtLang);
QedEditor.options.lang = config.options.txtLang;
// add 'ebooksettings' backstage task
if (config.tasks) {
config.tasks.ebookSettings = {
text: EbookDictionary.localize('Ebook Settings'),
tooltip: "Change the settings of the ebook.", // Localize
content: "<<ebooksettings inline>>",
currentTheme: DataTiddler.getData(Emathbook.config.userdatatiddler, 'ebooktheme', 'default'),
currentLang: config.options.txtLang
}
// config.backstageTasks.splice(config.backstageTasks.indexOf("importTask"),0,"ebookTheme");
config.backstageTasks.push("ebookSettings");
}
// Set the current theme.
jQuery('body').attr('ebooktheme',config.tasks.ebookSettings.currentTheme);
config.macros.ebooksettings = {
//}}}
// //
//{{{
label: "Ebook Settings",
tooltip: "Change the settings of the ebook.",
linkTooltip: "Settings: ",
themeData: [
{"themeid":"default","name":"Default theme"}
],
langData: [
{"langid": "en", "name": "English"},
{"langid": "et", "name": "Eesti"},
{"langid": "fi", "name": "Suomi"},
{"langid": "sv", "name": "Svenska"}
],
checkData: [
{
"checkid": "stepbystep",
"variable": "showstepbystep",
"name": {
"en": "Step by step derivations",
"fi": "Päättelyketjut askeleittain",
"sv": "\"Step by step\" härledningar",
"et": "\"Step by step\" lahenduskäik"
}
},
{
"checkid": "mqpanelautoshowhide",
"variable": "mqpanelautoshowhide",
"name": {
"en": "Show and hide mathpanel automatically.",
"fi": "Näytä ja piilota matikkapaneli automaattisesti.",
"sv": "Visa och göm matematikpanelen automatiskt.",
"et": "Näita ja peida matemaatikapaneel automaatselt."
}
},
{
"checkid": "eulexiafontuse",
"variable": "eulexiafontuse",
"name": {
"en": "Eulexia font",
"fi": "Eulexia-kirjasin",
"sv": "Eulexia font",
"et": "Eulexia font"
}
},
],
checkHandlers: {
eulexiafontuse: function(){
if (Emathbook.options.user.eulexiafontuse) {
jQuery('body').addClass('eulexia');
} else {
jQuery('body').removeClass('eulexia');
}
}
},
//}}}
// // macro definition
//{{{
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleSettingsPanel); return; }
var id=params.shift();
this.createSettingsPanel(place,id+"_settingsPanel",params);
jQuery('#'+id+'_settingsPanel').css('position','static').css('display','block');
if (typeof(jQuery.fn.emathonoff) === 'function'){
jQuery('#'+id+'_settingsPanel input[type="checkbox"]').emathonoff({
texts: ['on','off'],
coloron: 'green',
coloroff: 'red'
});
}
},
//}}}
//{{{
createSettingsPanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length){
panel_id="_settingsPanel";
}
// remove existing panel (if any)
var panel=jQuery('#'+panel_id);
panel.remove();
// set styles for this panel
setStylesheet(this.css,"settingsPanel");
// create new panel
var title='';
if (params && params[0]){
title=params.shift();
}
panel=createTiddlyElement(place,"span",panel_id,"settingsPanel",null);
var html=this.html;
// var html=this.html.replace(/%id%/g,panel_id);
// html=html.replace(/%title%/g,title);
html=html.replace(/%themelist%/g, this.themeList());
html=html.replace(/%langlist%/g, this.langList());
html=html.replace(/%checklist%/g, this.checkList());
jQuery(panel).empty().append(html);
return panel;
},
//}}}
//{{{
toggleSettingsPanel:
function (e) {
if (!e) e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_settingsPanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.ebooksettings.createSettingsPanel(parent,"_settingsPanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
//}}}
// // TODO
//{{{
themeList:
function() {
var out="<table class=\"themelist\">\n";
for (var th=0; th<this.themeData.length; th++) {
var options = config.tasks.ebookSettings.currentTheme == this.themeData[th].themeid ? 'checked="checked" ' : '';
var label=this.themeData[th].name;
var value=this.themeData[th].themeid;
out +='<tr><td><input type="radio" name="themechoose" value="%1" onchange="config.macros.ebooksettings.onChangeTheme(this);" %2 /></td><td>%0</td></tr>\n'.format([label,value,options]);
}
out += '</table>\n';
return out;
},
langList:
function() {
var out="<table class=\"langlist\">\n";
for (var lang=0; lang<this.langData.length; lang++) {
var options = config.tasks.ebookSettings.currentLang == this.langData[lang].langid ? 'checked="checked" ' : '';
var label=this.langData[lang].name;
var value=this.langData[lang].langid;
out +='<tr><td><input type="radio" name="langchoose" value="%1" onchange="config.macros.ebooksettings.onChangeLang(this);" %2 /></td><td>%0</td></tr>\n'.format([label,value,options]);
}
out += '</table>\n';
return out;
},
checkList:
function() {
var out="<table class=\"checklist\">\n";
for (var check=0; check<this.checkData.length; check++) {
var label=this.checkData[check].name[config.tasks.ebookSettings.currentLang] || this.checkData[check].name['en'];
var value=this.checkData[check].checkid;
var variable = this.checkData[check].variable;
var options = Emathbook.options.user[variable] ? 'checked="checked" ' : '';
out +='<tr><td><input type="checkbox" name="%1check" value="%1" variable="%3" onchange="config.macros.ebooksettings.onChangeCheck(this);" %2 /></td><td>%0</td></tr>\n'.format([label,value,options,variable]);
}
out += '</table>\n';
return out;
},
//}}}
// // interface definition
//{{{
css:
".settingsPanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
margin-left: auto; margin-right: auto;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em; text-align:left }\
.settingsPanel form { display:inline-block;border:0;padding:0;margin:0;vertical-align: top; }\
.settingsPanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.settingsPanel li { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.settingsPanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.settingsPanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.settingsPanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.settingsPanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; }\
.settingsPanel .chk { width:auto;border:0; }\
.settingsPanel .btn { width:auto; }\
.settingsPanel .btn2 { width:49%; }\
.settingsPanel ul.themelist {list-style: none;}\
.settingsPanel table.themelist td:first-child {width: 2.5em;}\
.settingsPanel ul.langlist {list-style: none;}\
.settingsPanel table.langlist td:first-child {width: 2.5em;}\
",
//}}}
//{{{
html:
'<form>\
<p>'+EbookDictionary.localize('Choose the theme')+'</p>\
%themelist%\
</form>\
<form>\
<p>'+EbookDictionary.localize('Choose the language')+'</p>\
%langlist%\
</form>\
<form>\
<p>'+EbookDictionary.localize('Settings')+'</p>\
%checklist%\
</form>',
//}}}
// // control processing
//{{{
onChangeTheme:
function(here) {
Emathbook.options.user.ebooktheme = here.value;
Emathbook.options.saveUserSettings();
// DataTiddler.setData(Emathbook.config.userdatatiddler, 'ebooktheme', here.value);
config.tasks.ebookSettings.currentTheme = here.value;
jQuery('body').attr('ebooktheme',config.tasks.ebookSettings.currentTheme);
},
onChangeLang:
function(here) {
DataTiddler.setData(Emathbook.config.userdatatiddler, 'lang', here.value);
config.tasks.ebookSettings.currentLang = here.value;
config.options.txtLang = config.tasks.ebookSettings.currentLang;
Emathbook.options.user.lang = config.tasks.ebookSettings.currentLang;
jQuery('body').attr('lang',config.options.txtLang);
QedEditor.options.lang = config.options.txtLang;
refreshAll();
var settingstask = jQuery('.backstageTask[task="ebookSettings"]');
var settingstext = settingstask.html();
settingstask.empty().append(EbookDictionary.localize('Ebook Settings') + settingstext[settingstext.length-1]);
},
onChangeCheck:
function(here) {
var variable = jQuery(here).attr('variable');
Emathbook.options.user[variable] = jQuery(here).attr('checked');
Emathbook.options.saveUserSettingsLocal();
if (typeof(config.macros.ebooksettings.checkHandlers[variable]) === 'function') {
config.macros.ebooksettings.checkHandlers[variable]();
}
}
};
//}}}
// // Load themes and other stuff
//{{{
(function(){
var themeTiddlers = store.getTaggedTiddlers('ThemeStyle');
var newcss = '';
for (var i = 0; i<themeTiddlers.length; i++){
var newTheme = {};
newTheme.themeid = store.getTiddlerText(themeTiddlers[i].title+'##themeid');
newTheme.name = store.getTiddlerText(themeTiddlers[i].title+'##name');
newTheme.author = store.getTiddlerText(themeTiddlers[i].title+'##author');
// newcss += store.getTiddlerText(themeTiddlers[i].title+'##css') + '\n';
newcss += store.getRecursiveTiddlerText(themeTiddlers[i].title).split(/\n!css\n/)[1].split(/\n![^\n]*\n/)[0] + '\n';
if (!!newTheme.themeid && !!newTheme.name){
config.macros.ebooksettings.themeData.push(newTheme);
}
}
setStylesheet(newcss);
config.macros.ebooksettings.checkHandlers.eulexiafontuse();
})()
//}}}
/***
|Name|EbookThemePlugin|
|Source|http://e-math.imped.fi|
|Documentation|http://e-math.imped.fi|
|Version|0.0.1|
|Author|Petri "pesasa" Salmela|
|License|CC-BY-SA 3.0 (plugin inspired by http://www.TiddlyTools.com/#AttachFilePlugin by Eric Shulman)|
|~CoreVersion|2.1|
|Type|plugin|
|Requires| |
|Description|Plugin for changing the theme of math ebook.|
!!!!!Documentation
>see [[EbookThemePluginInfo]]
!!!!!Inline interface (live)
>see [[EbookTheme]] (shadow tiddler)
><<tiddler EbookTheme>>
!!!!!Revisions
<<<
2012.02.03 0.0.1 First version
<<<
!!!!!Code
***/
// // version
//{{{
version.extensions.EbookThemePlugin= {major: 0, minor: 0, revision: 1, date: new Date(2012,2,3)};
// shadow tiddler
config.shadowTiddlers.EbookTheme="<<ebooktheme inline>>";
// add 'ebooktheme' backstage task
if (config.tasks) { // for TW2.2b or above
config.tasks.ebookTheme = {
text: "ebooktheme",
tooltip: "Change the theme of ebook content.",
content: "<<ebooktheme inline>>",
currentTheme: DataTiddler.getData(Emathbook.config.userdatatiddler, 'ebooktheme', 'default')
}
// config.backstageTasks.splice(config.backstageTasks.indexOf("importTask"),0,"ebookTheme");
config.backstageTasks.push("ebookTheme");
}
// Set the current theme.
jQuery('body').attr('ebooktheme',config.tasks.ebookTheme.currentTheme);
// Set current language
config.options.txtLang = DataTiddler.getData(Emathbook.config.userdatatiddler, 'lang', 'fi');
jQuery('body').attr('lang', config.options.txtLang);
QedEditor.options.lang = config.options.txtLang;
config.macros.ebooktheme = {
//}}}
// //
//{{{
label: "ebook theme",
tooltip: "Change the theme of ebook content.",
linkTooltip: "Theme: ",
themeData: [
{"themeid":"default","name":"Default theme"}
],
//}}}
// // macro definition
//{{{
handler:
function(place,macroName,params) {
if (params && !params[0])
{ createTiddlyButton(place,this.label,this.tooltip,this.toggleThemePanel); return; }
var id=params.shift();
this.createThemePanel(place,id+"_themePanel",params);
document.getElementById(id+"_themePanel").style.position="static";
document.getElementById(id+"_themePanel").style.display="block";
},
//}}}
//{{{
createThemePanel:
function(place,panel_id,params) {
if (!panel_id || !panel_id.length) var panel_id="_themePanel";
// remove existing panel (if any)
var panel=document.getElementById(panel_id); if (panel) panel.parentNode.removeChild(panel);
// set styles for this panel
setStylesheet(this.css,"themePanel");
// create new panel
var title=""; if (params && params[0]) title=params.shift();
panel=createTiddlyElement(place,"span",panel_id,"themePanel",null);
var html=this.html;
// var html=this.html.replace(/%id%/g,panel_id);
// html=html.replace(/%title%/g,title);
html=html.replace(/%themelist%/g,this.themeList());
panel.innerHTML=html;
return panel;
},
//}}}
//{{{
toggleThemePanel:
function (e) {
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = document.getElementById("_themePanel");
if (panel==undefined || panel.parentNode!=parent)
panel=config.macros.attach.createThemePanel(parent,"_attachPanel");
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
},
//}}}
// // TODO
//{{{
themeList:
function() {
var out="<table class=\"themelist\">\n";
for (var th=0; th<this.themeData.length; th++) {
var options = config.tasks.ebookTheme.currentTheme == this.themeData[th].themeid ? 'checked="checked" ' : '';
var label=this.themeData[th].name;
var value=this.themeData[th].themeid;
out +='<tr><td><input type="radio" name="themechoose" value="%1" onchange="config.macros.ebooktheme.onChangeTheme(this);" %2 /></td><td>%0</td></tr>\n'.format([label,value,options]);
}
out += '</table>\n';
return out;
},
//}}}
// // interface definition
//{{{
css:
".themePanel { display: none; position:absolute; z-index:10; width:35em; right:105%; top:0em;\
margin-left: auto; margin-right: auto;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;-webkit-border-radius:1em; text-align:left }\
.themePanel form { display:inline;border:0;padding:0;margin:0; }\
.themePanel select { width:99%;margin:0px;font-size:8pt;line-height:110%;}\
.themePanel li { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
.themePanel textarea { width:98%;margin:0px;height:2em;font-size:8pt;line-height:110%}\
.themePanel table { width:100%;border:0;margin:0;padding:0;color:inherit; }\
.themePanel tbody, .attachPanel tr, .attachPanel td { border:0;margin:0;padding:0;color:#000; }\
.themePanel .box { border:1px solid black; padding:.3em; margin:.3em 0px; background:#f8f8f8; \
-moz-border-radius:5px;-webkit-border-radius:5px; }\
.themePanel .chk { width:auto;border:0; }\
.themePanel .btn { width:auto; }\
.themePanel .btn2 { width:49%; }\
.themePanel ul.themelist {list-style: none;}\
.themePanel table.themelist td:first-child {width: 2.5em;}\
",
//}}}
//{{{
html:
'<form>\
<p>Choose the theme</p>\
%themelist%\
</form>',
//}}}
// // control processing
//{{{
onChangeTheme:
function(here) {
testilogit.here = here;
DataTiddler.setData(Emathbook.config.userdatatiddler, 'ebooktheme', here.value);
config.tasks.ebookTheme.currentTheme = here.value;
jQuery('body').attr('ebooktheme',config.tasks.ebookTheme.currentTheme);
}
};
//}}}
// // Load themes
//{{{
(function(){
var themeTiddlers = store.getTaggedTiddlers('ThemeStyle');
var newcss = '';
for (var i = 0; i<themeTiddlers.length; i++){
var newTheme = {};
newTheme.themeid = store.getTiddlerText(themeTiddlers[i].title+'##themeid');
newTheme.name = store.getTiddlerText(themeTiddlers[i].title+'##name');
newTheme.author = store.getTiddlerText(themeTiddlers[i].title+'##author');
// newcss += store.getTiddlerText(themeTiddlers[i].title+'##css') + '\n';
newcss += store.getRecursiveTiddlerText(themeTiddlers[i].title).split(/\n!css\n/)[1].split(/\n![^\n]*\n/)[0] + '\n';
if (!!newTheme.themeid && !!newTheme.name){
config.macros.ebooktheme.themeData.push(newTheme);
}
}
setStylesheet(newcss);
})()
//}}}
!usage
{{{
<<svgimg [[agpl-logo.svg]] [[floatright]]>>
}}}
!preview
<<svgimg [[agpl-logo.svg]] [[right]]>>
!link
http://www.gnu.org/licenses/agpl-3.0.html
!data
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="53"
viewbox="0 0 256 106"
id="svg3314"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="New document 4">
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-249.11103,-219.39217)">
<g
id="g2875"
transform="matrix(0.7699756,0,0,0.7699756,222.86081,-303.01221)">
<path
inkscape:connector-curvature="0"
d="m 225.50908,761.79412 c 0,0 -0.007,0 -0.007,0 -0.61733,0 -1.1624,0.20365 -1.67471,0.61745 -0.38093,0.30204 -0.6437,0.70934 -0.85386,1.16252 0,0 0.0263,0 0.0263,0 0.21015,-0.45318 0.47293,-0.86048 0.84723,-1.16252 0.51231,-0.4138 1.05738,-0.61082 1.6617,-0.61745 z"
id="path2877"
style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<path
inkscape:connector-curvature="0"
d="m 225.52872,761.79412 c -0.007,0 -0.0131,0 -0.0196,0 0.63708,0.007 1.05739,0.2234 1.3398,0.68971 0.12477,0.19702 0.1904,0.49256 0.1904,0.86686 0,0.0658 -0.0131,0.15114 -0.0196,0.2234 0,0 0.0262,0 0.0262,0 0,-0.0723 0.0131,-0.15764 0.0131,-0.2234 0,-0.3743 -0.0591,-0.66984 -0.1839,-0.86686 -0.28241,-0.47293 -0.70933,-0.68971 -1.34641,-0.68971 z"
id="path2879"
style="fill:#bd0000;fill-opacity:1;fill-rule:evenodd;stroke:none" />
<g
transform="matrix(0.385154,0,0,0.385154,330.53849,1073.2023)"
id="g2881"
style="fill:#663366;fill-opacity:1">
<g
transform="matrix(1.705222,0,0,1.705222,-769.6823,-728.9956)"
id="g2883"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.35,-14 3.35,-14 0,0 12.12,0 12.12,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85,0 8.4,0 8.4,0 8.4,0 0,36 0,36 z"
id="path2885"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-725.4318,-711.9434)"
id="g2887"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5.94 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.1,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z"
id="path2889"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-690.253,-711.9434)"
id="g2891"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73,8.08 0.34,15.86 0,22.65 3.52,26 10.78,26 c 2.79,0 6.49,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z"
id="path2893"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-645.0305,-711.9434)"
id="g2895"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72,8.08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z"
id="path2897"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-583.796,-711.9434)"
id="g2899"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 22.74,26 C 22.8,22.83 23.56,17.85 24.35,14.58 24.35,14.58 27.56,1 27.56,1 25.52,0.31 22.34,0 19.28,0 6.86,0 0.7,9.2 0.27,17.82 0,23.23 2.93,26 7.49,26 c 2.95,0 6.28,-1.43 8.87,-5.73 0,0 0.11,0 0.11,0 -0.2,2.07 -0.44,4.08 -0.57,5.73 0,0 6.84,0 6.84,0 z M 17.61,11.72 C 16.15,18.08 13.17,20 10.95,20 8.88,20 7.98,18.53 8.1,16.39 8.34,11.56 12.16,6 16.98,6 c 0.78,0 1.39,-0.14 1.96,-0.28 0,0 -1.33,6 -1.33,6 z"
id="path2901"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-536.6807,-711.9434)"
id="g2903"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 0,24.82 c 1.44,1.12 4.46,1.13 7.61,1.18 6.73,0.05 11.81,-2.89 12.11,-8.29 0.17,-3.6 -2.62,-5.73 -5.35,-7.16 C 12.4,9.6 11.41,8.69 11.46,7.63 11.53,6.2 12.87,6 14.84,6 c 2.22,0 4,0.27 5.02,0.47 0,0 2.02,-5.42 2.02,-5.42 C 20.73,0.36 18.43,0 15.48,0 8.95,0 4.17,3.45 3.9,8.69 c -0.16,3.24 2.17,5.42 4.99,6.9 2.28,1.17 3.06,2.07 3,3.34 C 11.82,20.21 10.68,20 8.61,20 6.18,20 3.49,19.68 2.07,19.46 2.07,19.46 0,24.82 0,24.82 z"
id="path2905"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-481.3463,-730.7008)"
id="g2907"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 7.45,37 c 0,0 6.05,-25 6.05,-25 0,0 -7.41,0 -7.41,0 0,0 -6.09,25 -6.09,25 0,0 7.45,0 7.45,0 z M 10.92,9 C 13.46,9 15.72,6.9 15.86,3.3 15.98,0.86 14.4,0 12.07,0 9.64,0 7.42,1.58 7.29,3.94 7.17,6.32 8.75,9 10.92,9 z"
id="path2909"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-456.9787,-710.7668)"
id="g2911"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 7.46,25.31 c 0,0 2.64,-11.26 2.64,-11.26 1.37,-5.73 4.32,-7.74 6.75,-7.74 1.92,0 2.48,0.82 2.39,2.01 -0.05,0.96 -0.2,1.97 -0.4,2.87 0,0 -3.36,14.12 -3.36,14.12 0,0 7.46,0 7.46,0 0,0 3.54,-14.81 3.54,-14.81 C 26.75,9.22 27.05,7.31 27.11,6.15 27.33,1.64 25.08,0 20.94,0 c -3.32,0 -6.55,1.54 -9.1,4.88 0,0 -0.1,0 -0.1,0 0,0 0.68,-4.57 0.68,-4.57 0,0 -6.58,0 -6.58,0 C 5.41,2.45 4.86,5.04 4.08,8.06 4.08,8.06 0,25.31 0,25.31 c 0,0 7.46,0 7.46,0 z"
id="path2913"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-389.5201,-728.9956)"
id="g2915"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 0,36 c 0,0 7.46,0 7.46,0 0,0 3.36,-14 3.36,-14 0,0 12.11,0 12.11,0 0,0 1.56,-6 1.56,-6 0,0 -12.17,0 -12.17,0 0,0 2.02,-9 2.02,-9 0,0 12.95,0 12.95,0 0,0 1.56,-7 1.56,-7 C 28.85,0 8.4,0 8.4,0 8.4,0 0,36 0,36 z"
id="path2917"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-345.2696,-711.9434)"
id="g2919"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="m 7.51,26 c 0,0 2.24,-9.4 2.24,-9.4 1.18,-5.09 3.67,-9.6 8.38,-9.6 0.42,0 0.83,0.21 1.14,0.26 0,0 1.82,-7.21 1.82,-7.21 -0.42,0 -0.88,-0.05 -1.4,-0.05 -3.47,0 -6.38,2.44 -8.32,5.94 0,0 -0.2,0 -0.2,0 C 11.46,4.23 11.71,2.61 11.9,1 11.9,1 5.47,1 5.47,1 5.11,3.08 4.53,7.15 3.66,10.82 3.66,10.82 0,26 0,26 c 0,0 7.51,0 7.51,0 z"
id="path2921"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-310.0908,-711.9434)"
id="g2923"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 20.06,19.25 C 17.99,20.26 15.63,20 12.88,20 10.71,20 9.03,19.62 8.11,18.88 7.63,18.07 7.43,16.81 7.47,16 17.6,16.27 23.99,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.73,0 0.73,8.08 0.34,15.86 0,22.65 3.53,26 10.78,26 c 2.79,0 6.5,-0.32 9.52,-1.23 0,0 -0.24,-5.52 -0.24,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.47,10 9.1,7.91 11.22,6 14.69,6 c 1.71,0 2.69,0.65 2.63,1.53 z"
id="path2925"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-264.8684,-711.9434)"
id="g2927"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 20.05,19.25 C 17.98,20.26 15.62,20 12.88,20 10.7,20 9.03,19.62 8.11,18.88 7.63,18.07 7.42,16.81 7.46,16 17.6,16.27 23.98,13.93 24.31,7.53 24.55,2.7 21.02,0 15.89,0 6.72,0 0.72,8.08 0.33,15.86 0,22.65 3.52,26 10.77,26 c 2.8,0 6.5,-0.32 9.53,-1.23 0,0 -0.25,-5.52 -0.25,-5.52 z M 17.32,7.53 C 17.2,9.91 14.26,10.05 8.46,10 9.1,7.91 11.21,6 14.68,6 c 1.71,0 2.7,0.65 2.64,1.53 z"
id="path2929"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-219.8846,-730.7008)"
id="g2931"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 23.31,0 C 23.31,0 20.5,11.36 20.5,11.36 19.48,10.94 18.15,11 17.11,11 7.53,11 0.75,19.2 0.3,28.08 0,34.34 3.34,37 7.64,37 c 3.01,0 6.18,-1.33 8.58,-4.77 0,0 0.1,0 0.1,0 0,0 -0.57,4.77 -0.57,4.77 0,0 6.78,0 6.78,0 0.31,-3 0.96,-6.57 1.69,-9.83 0,0 6.49,-27.17 6.49,-27.17 0,0 -7.4,0 -7.4,0 z M 17.47,24.42 C 16.3,29.35 13.54,31 11.36,31 9.19,31 7.98,29.49 8.13,26.8 8.38,21.82 11.8,17 16.25,17 c 1.25,0 2.32,0.19 2.91,0.47 0,0 -1.69,6.95 -1.69,6.95 z"
id="path2933"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-169.2225,-711.9434)"
id="g2935"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 10.61,26 C 19.31,26 26.02,19.41 26.49,10.44 26.78,4.5 23.08,0 16.25,0 7.23,0 0.76,7.3 0.31,16.12 0,22.54 4.14,26 10.61,26 z m 1.17,-6 C 9.24,20 7.84,18.38 7.99,15.96 8.19,11.93 10.68,6 14.97,6 c 2.96,0 3.87,2.27 3.75,4.5 -0.22,4.4 -2.9,9.5 -6.94,9.5 z"
id="path2937"
style="fill:#663366;fill-opacity:1" />
</g>
<g
transform="matrix(1.705222,0,0,1.705222,-120.5213,-711.9434)"
id="g2939"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none">
<path
inkscape:connector-curvature="0"
d="M 7.2,26 C 7.2,26 9.9,14.58 9.9,14.58 11.03,9.49 13.85,6 16.38,6 c 1.82,0 2.32,1.33 2.23,3.07 -0.05,0.9 -0.25,1.91 -0.46,2.91 0,0 -3.34,14.02 -3.34,14.02 0,0 7.2,0 7.2,0 0,0 2.7,-11.47 2.7,-11.47 C 25.95,9.28 28.61,6 31.09,6 c 1.71,0 2.42,1.22 2.34,2.96 -0.05,1.01 -0.26,2.12 -0.52,3.13 0,0 -3.24,13.91 -3.24,13.91 0,0 7.25,0 7.25,0 0,0 3.49,-14.81 3.49,-14.81 0.27,-1.33 0.58,-3.4 0.63,-4.46 C 41.26,2.33 39.11,0 35.23,0 31.91,0 28.68,1.5 26.23,4.66 26.14,2.38 24.51,0 20.47,0 17.2,0 14.08,1.48 11.58,4.83 c 0,0 -0.1,0 -0.1,0 0,0 0.67,-3.83 0.67,-3.83 0,0 -6.42,0 -6.42,0 C 5.31,3.14 4.8,5.73 4.02,8.75 4.02,8.75 0,26 0,26 c 0,0 7.2,0 7.2,0 z"
id="path2941"
style="fill:#663366;fill-opacity:1" />
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path2943"
sodipodi:nodetypes="cccccssccccscccsccc"
d="m 242.27371,772.00406 c 0.26666,0.68537 0.5332,1.3697 0.81093,2.03897 0.42773,0.90933 0.922,1.77974 1.51639,2.59227 3.21051,4.36413 8.58716,6.75366 15.41353,7.34862 0,0 7.34302,0 7.34302,0 2.32173,-0.18116 4.75464,-0.51882 7.27636,-1.01207 4.34906,-0.85043 8.95929,-2.15678 13.74726,-3.90261 3.62705,-1.32245 7.3541,-2.88712 11.13662,-4.70567 8.23729,-3.94873 16.74671,-9.04148 25.09506,-15.18751 2.74946,-2.02242 5.38772,-4.09758 7.92063,-6.20767 2.32173,-1.93179 4.54905,-3.89371 6.67649,-5.8772 5.93759,-5.72219 10.42009,-11.53376 12.95848,-16.63667 2.64386,-5.31398 3.17158,-9.85744 1.00533,-12.71967 -1.32747,-1.7569 -3.54931,-2.69843 -6.40983,-2.91999 12.88633,-9.6692 20.3959,-21.3985 17.70204,-28.79369 -0.85545,-2.36008 -2.73838,-4.12086 -5.43784,-5.09458 -1.19973,-0.43149 -2.54946,-0.70488 -4.02144,-0.82931 0,0 -3.96585,0 -3.96585,0 -5.53772,0.39942 -13.59076,2.38234 -20.42273,5.73052"
style="fill:#ffffff;fill-opacity:0;fill-rule:evenodd;stroke:#663266;stroke-width:3.28386545;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
d="m 62.777261,682.66638 c 0,0 -22.84339,99.66531 -22.84339,99.66531 0.0066,0 60.091419,0 60.104559,0 26.42484,0 105.67884,0 105.67884,0 1.2e-4,0 54.96371,0 54.96371,0 -6.54796,-0.57145 -11.71765,-2.87011 -14.79791,-7.06027 -0.57133,-0.77509 -1.04346,-1.60999 -1.45715,-2.48348 -0.26277,-0.64359 -0.5098,-1.293 -0.75945,-1.94971 -0.65682,-2.08863 -0.91869,-4.40613 -0.80043,-6.87568 0.32842,-6.883 3.5581,-15.07028 9.15381,-23.64386 5.94375,-9.11134 14.55819,-18.66102 25.22417,-27.52283 2.39067,-1.98475 4.86262,-3.94473 7.45021,-5.84947 3.19852,-2.35311 6.4217,-4.52039 9.64637,-6.54715 11.881,-7.48001 23.73254,-12.71397 34.23437,-15.37255 -10.03552,3.27397 -21.3098,8.83212 -32.4487,16.39877 -0.40067,0.27054 -0.79632,0.5477 -1.19049,0.82098 -6.18016,4.28216 -11.77917,8.82996 -16.66554,13.42273 -15.72323,14.78398 -24.0338,30.10322 -20.25732,39.07804 0.26928,0.61733 0.59027,1.20681 0.96458,1.76513 4.05888,5.97 14.11814,7.00193 26.86612,3.7969 0.86698,-0.21666 1.73396,-0.4622 2.62708,-0.71835 4.07201,-1.17554 8.39527,-2.76338 12.8482,-4.72051 1.07052,-0.47293 2.15256,-0.95887 3.24282,-1.4778 0.11164,-0.0525 0.21666,-0.10502 0.3283,-0.16415 14.05501,-6.98345 24.85648,-15.01891 27.19453,-19.84684 0.51232,-1.05019 0.63548,-1.94559 0.28732,-2.64763 -1.66821,-3.38242 -13.34145,-1.09733 -27.48185,5.02838 -1.13615,0.49267 -2.28554,0.99951 -3.44806,1.53933 0.94574,-0.87805 1.93019,-1.75953 2.93495,-2.62708 1.60257,-1.38055 3.26176,-2.73051 5.02848,-4.0638 2.76498,-2.09376 5.56032,-3.98662 8.31229,-5.66465 12.88587,-9.72159 19.40027,-18.91764 18.04072,-22.33031 -0.25615,-0.64301 -0.80122,-1.08524 -1.64195,-1.35464 -2.68621,-0.85442 -7.58902,0.16541 -13.5459,2.60665 -4.91274,2.01501 -10.55524,5.00338 -16.27572,8.72277 0,0 -0.77988,0.51312 -0.77988,0.51312 0,0 -0.14372,0.0821 -0.14372,0.0821 0,0 -2.75013,1.82665 -2.75013,1.82665 0,0 1.58031,-2.89385 1.58031,-2.89385 2.34467,-4.2921 6.16384,-8.77026 10.91882,-12.93028 3.48744,-3.04157 7.47167,-5.90734 11.76034,-8.41491 1.6222,-0.94974 3.24201,-1.83178 4.86422,-2.62708 1.6617,-0.81184 3.32409,-1.53328 4.9463,-2.17561 4.71308,-1.86387 9.89054,-4.21767 13.81404,-4.52565 -0.3573,0 -11.69996,1.22131 -11.69996,1.22131 0,0 -37.14877,0 -37.14877,0 0,0 -163.80326,0 -163.80326,0 0,0 -73.075879,0 -73.075879,0 z m 177.933719,0.14371 c -0.64359,9.82331 1.26103,24.21153 5.58258,40.18623 0.76846,2.84249 1.60497,5.73531 2.52446,8.66124 0.57144,1.80679 1.16092,3.58527 1.76512,5.33624 -0.35467,0.52145 -0.71173,1.03969 -1.04677,1.55988 -5.39206,8.26343 -8.54378,16.07287 -9.3385,22.86386 -2.27904,-7.63171 -3.99473,-15.99091 -4.96685,-24.85477 -0.27579,-2.53965 -0.49165,-5.05098 -0.63616,-7.53229 -1.06401,-18.02383 1.28888,-34.36245 6.11612,-46.22039 z m -107.60809,12.78645 c 0.12294,-0.003 0.24417,0 0.3694,0 0,0 24.28013,0 24.28013,0 2.07539,0 3.68036,0.38903 4.82313,1.16994 1.13615,0.78548 1.56228,1.80154 1.29299,3.03757 0,0 -2.89385,13.07388 -2.89385,13.07388 0,0 -8.55862,0 -8.55862,0 0,0 2.81178,-12.72492 2.81178,-12.72492 0,0 -21.42715,0 -21.42715,0 0,0 -7.73764,34.97305 -7.73764,34.97305 0,0 -2.79135,12.6635 -2.79135,12.6635 0,0 21.40671,0 21.40671,0 0,0 0.0206,-0.0821 0.0206,-0.0821 0,0 4.28958,-19.37493 4.28958,-19.37493 0,0 -10.05685,0 -10.05685,0 0,0 0.96469,-4.37155 0.96469,-4.37155 0,-1.1e-4 18.61537,0 18.61537,0 0,-1.1e-4 -5.33624,24.1774 -5.33624,24.1774 -0.0723,0.34417 -0.19874,0.65592 -0.36951,0.9647 -0.44006,0.80122 -1.20761,1.4875 -2.27812,2.05244 -1.48431,0.78148 -3.26085,1.16982 -5.33636,1.16982 0,0 -24.25947,0 -24.25947,0 -2.07539,0 -3.68036,-0.38834 -4.82324,-1.16982 -1.13615,-0.7816 -1.56884,-1.77974 -1.29299,-3.01714 0,0 10.69314,-48.33436 10.69314,-48.33436 0.27579,-1.23603 1.13615,-2.25209 2.62696,-3.03757 0.0526,-0.0283 0.11176,-0.0347 0.16427,-0.0615 1.3608,-0.6816 2.95778,-1.0648 4.80269,-1.10841 z m 38.05183,0 c -1.2e-4,0 30.5604,0 30.5604,0 2.04913,0 3.65981,0.38903 4.8027,1.16994 1.14927,0.78548 1.58933,1.80154 1.31354,3.03757 0,0 -5.70575,25.77837 -5.70575,25.77837 -0.26928,1.22816 -1.15019,2.23018 -2.64763,3.01703 -1.49744,0.78947 -3.26005,1.19037 -5.31581,1.19037 0,0 -22.20714,0 -22.20714,0 0,0 -4.28947,19.35427 -4.28947,19.35427 0,0 -0.69781,3.18128 -0.69781,3.18128 0,0 -8.37392,0 -8.37392,0 0,0 0.63628,-2.87342 0.63628,-2.87342 0,0 11.92461,-53.85541 11.92461,-53.85541 z m 42.21812,0 c 0,0 8.37381,0 8.37381,0 0,0 -9.48211,42.83397 -9.48211,42.83397 0,0 -2.07299,9.35905 -2.07299,9.35905 0,0 20.03165,0 20.03165,0 0.21015,1.53614 0.45557,3.045 0.71835,4.53581 0,0 -30.12948,0 -30.12948,0 0,0 2.38074,-10.75466 2.38074,-10.75466 0,0 10.18003,-45.97417 10.18003,-45.97417 z m -34.84999,4.55647 c 0,0 -5.56214,25.08045 -5.56214,25.08045 0,0 20.87316,0 20.87316,0 0,0 5.54149,-25.08045 5.54149,-25.08045 0,0 -20.85251,0 -20.85251,0 z m -44.50903,59.19428 c 0.082,-0.003 0.16381,0 0.24634,0 0.972,0 1.82094,0.17065 2.50391,0.49256 0.72909,0.34154 1.25042,0.84883 1.53934,1.51879 0.28241,0.6502 0.35626,1.38819 0.20524,2.19604 0,0 -0.0615,0.30787 -0.0615,0.30787 0,0 -2.40129,0 -2.40129,0 -1.1e-4,0 0.0204,-0.28732 0.0204,-0.28732 0.0621,-0.56448 -0.008,-1.0083 -0.22567,-1.31354 -0.0284,-0.0382 -0.0696,-0.0888 -0.10274,-0.12317 -0.0541,-0.0554 -0.1355,-0.11849 -0.20513,-0.16415 -0.33606,-0.21175 -0.86161,-0.32841 -1.53933,-0.32841 -0.89986,0 -1.57221,0.15673 -2.0319,0.47201 -0.44667,0.30867 -0.72908,0.65352 -0.82098,1.06732 -0.092,0.4203 0.059,0.64119 0.16415,0.75933 0.003,0.003 0.0166,0.0169 0.0205,0.0205 0.1331,0.11335 0.59519,0.37933 2.0319,0.71836 1.30041,0.31528 2.16157,0.59849 2.64763,0.84152 0.73559,0.3743 1.2495,0.85956 1.51878,1.45714 0.26929,0.5912 0.32842,1.28318 0.16415,2.0319 -0.16415,0.72909 -0.53605,1.40144 -1.08775,2.0319 -0.54507,0.63046 -1.23877,1.12964 -2.07299,1.4778 -0.82748,0.34154 -1.73544,0.53355 -2.66806,0.53355 -1.18227,0 -2.13132,-0.17888 -2.87342,-0.53355 -0.77498,-0.36779 -1.33409,-0.94825 -1.66239,-1.70359 -0.31529,-0.73548 -0.38263,-1.5705 -0.20536,-2.48337 0,0 0.0616,-0.28732 0.0616,-0.28732 0,0 2.36031,0 2.36031,0 0,0 -0.0205,0.28732 -0.0205,0.28732 -0.0591,0.54507 -8e-4,0.98513 0.1436,1.31354 0.13801,0.31529 0.40067,0.57635 0.82098,0.77988 0.44667,0.21678 1.00487,0.32842 1.64195,0.32842 0.57144,0 1.09357,-0.096 1.55988,-0.26677 0.45969,-0.16427 0.82509,-0.38093 1.08775,-0.65683 0.25616,-0.27579 0.40638,-0.56733 0.47202,-0.88251 0.0657,-0.28241 0.0501,-0.52133 -0.0615,-0.71835 -0.12477,-0.21015 -0.37191,-0.39656 -0.75945,-0.55409 0,-1.2e-4 -2.01135,-0.5953 -2.01135,-0.5953 -1.12302,-0.28241 -1.87916,-0.5517 -2.31921,-0.82098 -0.5977,-0.35456 -1.02862,-0.80945 -1.25202,-1.35452 -0.22328,-0.53857 -0.24702,-1.13547 -0.10251,-1.78567 0.15103,-0.69621 0.48675,-1.35863 1.00568,-1.94971 0.52544,-0.5977 1.2035,-1.06652 2.01135,-1.37518 0.71424,-0.2678 1.46582,-0.42488 2.25757,-0.45147 z m 21.55043,0.041 c 0.1299,-0.01 0.25205,0 0.38994,0 0,0 1.47769,0.16415 1.47769,0.16415 0,0 0.49257,0.0411 0.49257,0.0411 1.1e-4,0 -0.71825,1.82665 -0.71825,1.82665 0,0 -0.14371,0.28732 -0.14371,0.28732 0,0 -1.12885,-0.10262 -1.12885,-0.10262 -0.33332,0 -0.57817,0.0515 -0.7389,0.16427 -0.0106,0.008 -0.0312,0.0324 -0.041,0.041 -0.0216,0.0189 -0.0578,0.0518 -0.0821,0.0822 -0.0989,0.12957 -0.21917,0.36118 -0.30787,0.77989 0,0 -0.0427,0.17727 -0.0821,0.32841 0.51881,0 1.76501,0 1.76501,0 0,0 -0.45147,2.0319 -0.45147,2.0319 0,0 -1.2906,0 -1.72403,0 -0.13139,0.59107 -1.74458,7.8196 -1.74458,7.8196 0,0 -2.38086,0 -2.38086,0 0,0 1.54755,-6.94612 1.74458,-7.8196 -0.40067,0 -1.37507,0 -1.37507,0 0,0 0.45147,-2.0319 0.45147,-2.0319 0,0 0.98022,0 1.35464,0 0.0656,-0.28241 0.16414,-0.63628 0.16414,-0.63628 0.14452,-0.65683 0.29554,-1.12884 0.49257,-1.45726 0.2694,-0.45318 0.64941,-0.83239 1.12884,-1.10829 0.39497,-0.22945 0.89438,-0.36666 1.45726,-0.41049 z m 5.6852,0.10262 c 0,0 -0.62235,2.80036 -0.77988,3.5097 0.45969,0 1.53922,0 1.53922,0 0,0 -0.45147,2.0319 -0.45147,2.0319 0,0 -1.13216,0 -1.53934,0 -0.12476,0.5647 -1.10829,4.9463 -1.10829,4.9463 0,0 -0.0821,0.52623 -0.0821,0.67726 1.2e-4,0.005 -4.5e-4,0.0168 0,0.0205 3.4e-4,0.002 -4.5e-4,0.0192 0,0.0205 5.7e-4,10e-4 0.0196,-8e-4 0.0204,0 0,0 0.24633,0.0204 0.24633,0.0204 0,0 1.12885,-0.0821 1.12885,-0.0821 0,0 -0.12317,1.82665 -0.12317,1.82665 0,0 0.0205,0.32841 0.0205,0.32841 0,0 -1.62141,0.1847 -1.62141,0.1847 -0.64359,0 -1.11572,-0.10502 -1.45726,-0.32841 -0.36117,-0.23641 -0.57133,-0.54998 -0.65671,-0.94404 -0.0131,-0.0723 -0.0411,-0.17739 -0.0411,-0.32841 0,-0.29554 0.0558,-0.79552 0.24634,-1.6625 0,0 0.86276,-3.86506 1.04666,-4.67941 -0.30867,0 -1.12873,0 -1.12873,0 0,0 0.45147,-2.0319 0.45147,-2.0319 0,0 0.80043,0 1.12884,0 0.10513,-0.47293 0.47202,-2.09354 0.47202,-2.09354 0,0 1.90884,-1.00567 1.90884,-1.00567 0,0 0.77988,-0.41049 0.77988,-0.41049 z m -75.631539,0.0821 c 0,0 9.23587,0 9.23587,0 0,0 -0.5131,2.29879 -0.5131,2.29879 0,0 -6.16135,0 -6.75245,0 -0.10506,0.46631 -0.52622,2.35449 -0.67728,3.03757 0.85381,0 5.84937,0 5.84937,0 0,0 -0.51311,2.29867 -0.51311,2.29867 0,0 -5.25827,0 -5.84937,0 -0.12479,0.57144 -1.25198,5.6441 -1.25198,5.6441 0,0 -2.48343,0 -2.48343,0 0,0 2.95548,-13.27913 2.95548,-13.27913 z m 12.37608,3.24293 c 0.09266,-0.0114 0.19392,0 0.28731,0 0.5911,0 1.13707,0.17979 1.66248,0.5541 0,0 0.328389,0.22579 0.328389,0.22579 0,0 -1.272509,2.09342 -1.272509,2.09342 0,0 -0.34892,-0.24634 -0.34892,-0.24634 -0.25612,-0.16415 -0.53196,-0.24622 -0.82095,-0.24622 -0.24958,0 -0.4819,0.0887 -0.71834,0.24622 -0.24958,0.16427 -0.45811,0.38184 -0.61571,0.67738 -0.27585,0.50569 -0.47783,1.07211 -0.61575,1.68293 0,0 -1.10832,5.04892 -1.10832,5.04892 0,0 -2.38079,0 -2.38079,0 0,0 2.19611,-9.8515 2.19611,-9.8515 0,0 2.2166,0 2.2166,0 0,0 -0.07638,0.29874 -0.10264,0.41038 0.10511,-0.0788 0.21591,-0.1871 0.30789,-0.24623 0.3181,-0.18983 0.65411,-0.30832 0.98515,-0.34885 z m 7.060299,0 c 0.14335,-0.0109 0.28446,0 0.43102,0 1.3398,0 2.35368,0.46951 3.01703,1.39562 0.41377,0.59758 0.63628,1.33649 0.63628,2.21659 0,0.48595 -0.0599,1.00899 -0.18472,1.58032 0,0 -0.18472,0.71835 -0.18472,0.71835 0,0 -6.02097,0 -6.6909,0 -0.0131,0.1379 -0.0205,0.28572 -0.0205,0.41049 0,0.51231 0.10511,0.91538 0.32838,1.21092 0.10612,0.14451 0.22914,0.27465 0.36944,0.36939 0.26454,0.1726 0.60601,0.26689 1.00572,0.26689 0.48599,0 0.9129,-0.1339 1.31353,-0.38994 0.38091,-0.24303 0.74543,-0.63137 1.06726,-1.16994 0,0 2.54499,0 2.54499,0 0,0 -0.22574,0.49256 -0.22574,0.49256 -0.48603,0.98524 -1.16417,1.7536 -2.01139,2.29879 -0.84722,0.54507 -1.85948,0.84141 -2.97601,0.84141 -1.45145,0 -2.53185,-0.46951 -3.20175,-1.39562 -0.663349,-0.90636 -0.806199,-2.15917 -0.451559,-3.73538 0.354699,-1.60257 1.062339,-2.88324 2.093469,-3.77647 0.92422,-0.80135 1.97295,-1.24585 3.14021,-1.33398 z m 10.69313,0 c 0.14326,-0.0109 0.28446,0 0.43092,0 1.33991,0 2.3538,0.46951 3.01714,1.39562 0.41379,0.59758 0.63616,1.33649 0.63616,2.21659 0,0.47944 -0.0599,0.99495 -0.1847,1.55977 0,0 -0.18469,0.7389 -0.18469,0.7389 0,0 -6.02097,0 -6.69087,0 -0.007,0.092 -0.014,0.17488 -0.0205,0.26677 -0.005,0.0345 0.002,0.0869 0,0.12317 -1.9e-4,0.006 0,0.0148 0,0.0205 0,0.0985 0.0139,0.19543 0.0205,0.28732 0.0328,0.37442 0.13054,0.68719 0.30786,0.9236 0.0338,0.046 0.0655,0.10274 0.1026,0.14372 0.30081,0.32179 0.72656,0.49256 1.27251,0.49256 0.48602,0 0.91945,-0.1339 1.3135,-0.38994 0.38104,-0.24303 0.74552,-0.63137 1.06732,-1.16994 0,0 2.56544,0 2.56544,0 0,0 -0.24623,0.49256 -0.24623,0.49256 -0.48606,0.98524 -1.16412,1.7536 -2.01135,2.29879 -0.84723,0.54507 -1.85953,0.84141 -2.976,0.84141 -1.45149,0 -2.53189,-0.46951 -3.20178,-1.39562 -0.43346,-0.59108 -0.63624,-1.34391 -0.63624,-2.23714 0,-0.1379 0.007,-0.28652 0.0205,-0.43104 0.0263,-0.34142 0.0788,-0.68628 0.16419,-1.0672 0.35465,-1.59595 1.0418,-2.88324 2.07293,-3.77647 0.92419,-0.80135 1.99344,-1.24585 3.16076,-1.33398 z m 29.12369,0 c 0.14669,-0.0113 0.28161,0 0.43104,0 1.36616,0 2.41613,0.46209 3.0991,1.37507 0.67657,0.91287 0.84072,2.14434 0.49267,3.69429 -0.26928,1.20852 -0.65842,2.18463 -1.19048,2.89397 -0.53195,0.70933 -1.21001,1.28888 -2.01135,1.68293 -0.79461,0.39405 -1.63614,0.59519 -2.48337,0.59519 -1.39242,0 -2.42925,-0.47613 -3.09921,-1.39562 -0.43343,-0.58457 -0.65671,-1.33728 -0.65671,-2.23714 0,-0.48594 0.0533,-1.00236 0.18469,-1.58031 0.39405,-1.76022 1.19859,-3.10081 2.38075,-3.96117 0.86778,-0.62647 1.82619,-0.98833 2.85287,-1.06721 z m 36.06102,0 c 0.17317,-0.0107 0.33344,0 0.51311,0 0.82749,0 1.47769,0.0837 1.97026,0.28732 0.52544,0.21016 0.89814,0.50729 1.10829,0.86196 0.20365,0.33492 0.30787,0.74632 0.30787,1.25201 0,0 -0.24622,1.49824 -0.24622,1.49824 0,0 -0.45159,2.0319 -0.45159,2.0319 -0.38754,1.73385 -0.47281,2.38405 -0.49256,2.62708 -0.0197,0.32841 0.0106,0.6485 0.10262,0.94415 0,0 0.16415,0.53354 0.16415,0.53354 0,0 -2.42184,0 -2.42184,0 0,0 -0.10262,-0.30786 -0.10262,-0.30786 -0.0394,-0.14441 -0.0279,-0.3283 -0.041,-0.49257 -0.4598,0.28241 -0.92029,0.53286 -1.33409,0.67726 -0.61082,0.21027 -1.24459,0.32842 -1.88829,0.32842 -1.1164,0 -1.9432,-0.29063 -2.44239,-0.86196 -0.38081,-0.42031 -0.55409,-0.93422 -0.55409,-1.51879 0,-0.22328 0.0296,-0.45478 0.0821,-0.6978 0.11164,-0.49919 0.31449,-0.96139 0.63628,-1.37519 0.31528,-0.40718 0.68799,-0.7421 1.10829,-0.98513 0.40718,-0.24302 0.86116,-0.41539 1.33409,-0.53365 0,0 1.45726,-0.24623 1.45726,-0.24623 1.12302,-0.13139 1.96124,-0.29474 2.56544,-0.47213 0.0131,-0.0656 0.0411,-0.1436 0.0411,-0.1436 0.0952,-0.42259 0.0833,-0.74027 -0.0205,-0.90305 -0.008,-0.0105 -0.0324,-0.0321 -0.0411,-0.0411 -0.0221,-0.0236 -0.0562,-0.0607 -0.0821,-0.0821 -0.24702,-0.19543 -0.66824,-0.28732 -1.23147,-0.28732 -0.63708,0 -1.10829,0.10422 -1.43659,0.30786 -0.32191,0.20354 -0.61985,0.57624 -0.88262,1.1083 0,0 -2.48337,0 -2.48337,0 0,0 0.22568,-0.49256 0.22568,-0.49256 0.29554,-0.68308 0.64781,-1.24962 1.08786,-1.68305 0.44006,-0.43343 1.03444,-0.76927 1.72403,-1.00568 0.52841,-0.17442 1.10556,-0.29017 1.72403,-0.3283 z m 10.40571,0 c 0.0927,-0.0114 0.19394,0 0.28732,0 0.5977,0 1.15761,0.17979 1.68305,0.5541 0,0 0.30786,0.22579 0.30786,0.22579 0,0 -1.27256,2.09342 -1.27256,2.09342 0,0 -0.34884,-0.24634 -0.34884,-0.24634 -0.25616,-0.16415 -0.51814,-0.24622 -0.80043,-0.24622 -0.24965,0 -0.49599,0.0887 -0.73891,0.24622 -0.24965,0.16427 -0.43103,0.38184 -0.59518,0.67738 -0.26929,0.50569 -0.47784,1.07211 -0.61574,1.68293 0,0 -1.12884,5.04892 -1.12884,5.04892 0,0 -2.38086,0 -2.38086,0 0,0 2.19616,-9.8515 2.19616,-9.8515 0,0 2.2166,0 2.2166,0 0,0 -0.0558,0.29874 -0.0821,0.41038 0.10502,-0.0788 0.20936,-0.1871 0.30787,-0.24623 0.313,-0.18983 0.63377,-0.30832 0.96458,-0.34885 z m 7.03983,0 c 0.14315,-0.0109 0.28447,0 0.43093,0 1.33991,0 2.36031,0.46951 3.01713,1.39562 0.42031,0.59758 0.63617,1.33649 0.63617,2.21659 0,0.48595 -0.0804,1.00899 -0.20524,1.58032 0,0 -0.16415,0.71835 -0.16415,0.71835 0,0 -6.02754,0 -6.69088,0 -0.0131,0.1379 -0.0411,0.28572 -0.0411,0.41049 0,0.51231 0.11175,0.91538 0.32841,1.21092 0.0338,0.046 0.086,0.10274 0.12317,0.14372 0.0216,0.0229 0.0594,0.0607 0.0821,0.0821 0.2936,0.26689 0.69325,0.41049 1.19038,0.41049 0.48605,0 0.91298,-0.1339 1.31354,-0.38994 0.38104,-0.24303 0.7389,-0.63137 1.06731,-1.16994 0,0 2.56556,0 2.56556,0 0,0 -0.24634,0.49256 -0.24634,0.49256 -0.48606,0.98524 -1.17074,1.7536 -2.01135,2.29879 -0.85385,0.54507 -1.85291,0.84141 -2.97604,0.84141 -1.45144,0 -2.51134,-0.46951 -3.18118,-1.39562 -0.66333,-0.90636 -0.82017,-2.15917 -0.47213,-3.73538 0.35467,-1.60257 1.04186,-2.88324 2.07299,-3.77647 0.93,-0.80135 1.99457,-1.24585 3.16074,-1.33398 z m -35.93785,0.1847 c 0,0 2.44239,0 2.44239,0 0,0 0.30124,5.84604 0.30786,5.93143 0.0985,-0.20936 0.175,-0.38549 0.1847,-0.41049 0,0 2.68872,-5.52094 2.68872,-5.52094 0,0 2.23714,0 2.23714,0 0,0 0.20525,5.77538 0.20525,5.80826 0.0656,-0.11815 3.058,-5.80826 3.058,-5.80826 0,0 2.42184,0 2.42184,0 0,0 -5.33624,9.8515 -5.33624,9.8515 0,0 -2.19604,0 -2.19604,0 0,0 -0.21267,-5.34194 -0.2258,-5.6441 -0.90636,1.85872 -2.75025,5.6441 -2.75025,5.6441 0,0 -2.25769,0 -2.25769,0 0,0 -0.77988,-9.8515 -0.77988,-9.8515 z m -57.34448,1.86763 c -0.56575,0.0239 -1.07959,0.22785 -1.55984,0.61574 -0.38091,0.30216 -0.63789,0.71675 -0.84148,1.16982 0,1.2e-4 4.04324,0 4.04324,0 0.007,-0.0721 0.0205,-0.16004 0.0205,-0.22568 0,-0.37441 -0.0665,-0.66504 -0.18472,-0.86207 -0.28894,-0.47281 -0.7175,-0.69781 -1.35459,-0.69781 -0.0382,0 -0.0854,-0.002 -0.12313,0 z m 10.69306,0 c -0.56574,0.0239 -1.07953,0.22785 -1.55983,0.61574 -0.38091,0.30216 -0.6313,0.71675 -0.84148,1.16982 0,1.2e-4 4.04326,0 4.04326,0 0.007,-0.0721 0.0206,-0.16004 0.0206,-0.22568 0,-0.37441 -0.0599,-0.66504 -0.1847,-0.86207 -0.0574,-0.096 -0.13504,-0.19154 -0.20524,-0.26677 -0.27431,-0.28332 -0.65169,-0.43104 -1.14939,-0.43104 -0.0382,0 -0.0854,-0.002 -0.12317,0 z m 82.71244,0 c -0.58183,0.0179 -1.12519,0.21495 -1.62152,0.61574 -0.3743,0.30216 -0.63126,0.71675 -0.84141,1.16982 0,1.2e-4 4.0227,0 4.0227,0 0.007,-0.0721 0.0206,-0.16004 0.0206,-0.22568 0,-0.37441 -0.0599,-0.66504 -0.1847,-0.86207 -0.28241,-0.46631 -0.71756,-0.69119 -1.35464,-0.69781 -0.0188,2.3e-4 -0.0223,-5.7e-4 -0.041,0 z m -53.77333,0.0411 c -0.54291,0.0644 -1.0478,0.3122 -1.51879,0.73879 -0.56482,0.51231 -0.97451,1.31685 -1.21092,2.38085 -0.0985,0.44656 -0.14371,0.8284 -0.14371,1.16983 0,0.46631 0.0895,0.8325 0.26688,1.10829 0.0471,0.0709 0.10982,0.14566 0.16415,0.20525 0.292,0.31003 0.69964,0.47213 1.21092,0.47213 0.66334,0 1.24791,-0.24714 1.80611,-0.75945 0.56482,-0.51882 0.96789,-1.33158 1.21092,-2.42184 0.22328,-0.99825 0.19211,-1.74366 -0.12317,-2.21659 -0.30205,-0.45969 -0.74381,-0.67726 -1.35453,-0.67726 -0.10364,0 -0.20729,-0.012 -0.30786,0 z m 37.08713,3.59166 c -0.5582,0.15114 -1.18387,0.2783 -2.01135,0.39006 -0.61733,0.0919 -1.05739,0.1888 -1.31354,0.28731 -0.22328,0.0919 -0.40307,0.21918 -0.55421,0.38995 -0.1444,0.16415 -0.24131,0.33651 -0.28732,0.53365 -0.0131,0.0788 -0.0205,0.16004 -0.0205,0.22568 0,0.005 -1.2e-4,0.0153 0,0.0205 6.8e-4,0.0156 -0.002,0.0465 0,0.0616 0.004,0.0297 0.0124,0.0748 0.0205,0.10251 0.003,0.009 0.0171,0.0322 0.0205,0.0411 0.007,0.0177 0.0116,0.0448 0.0206,0.0616 0.009,0.0166 0.03,0.0455 0.041,0.0615 0.0172,0.0236 0.0406,0.0599 0.0616,0.0821 0.16415,0.1839 0.49176,0.26677 0.96458,0.26677 0.51893,0 1.018,-0.0985 1.4778,-0.3283 0.45319,-0.22339 0.81847,-0.55672 1.08775,-0.94415 0.19703,-0.27579 0.35467,-0.70032 0.49257,-1.25201 z m -125.364659,-16.45612 55.082599,-56.87199 8.99518,0 -13.2998,56.87199 -7.398629,0 3.776339,-16.37106 -23.091518,0 -15.692032,16.37106 -8.372139,0 m 29.675679,-22.22896 18.88598,0 3.48449,-14.27618 c 1.40629,-5.66388 2.75996,-10.38381 4.06102,-14.1598 -2.60007,3.25873 -6.04001,7.1252 -10.31982,11.59939 L 86.12566,729.8159"
style="fill:#663366;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path2945" />
</g>
</g>
</svg>
!usage
{{{[img[angle-down.png]]}}}
[img[angle-down.png]]
!notes
//none//
!type
image/png
!file
./images/angle-down.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLEQw3FkaRq6YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAATUlEQVQ4y2NgGAUDDxjRBWzsbP5DmZJHDh15YWNnI8HAwPCcgYGB4cihIxjqmbAYKgmlnyNrRhLH7wKoK5A1wl1DtAFohuDUPAoGCwAAcPgV1OHzskAAAAAASUVORK5CYII=
!usage
{{{[img[angle-right.png]]}}}
[img[angle-right.png]]
!notes
//none//
!type
image/png
!file
./images/angle-right.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLEQw3AcVCLmEAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAARElEQVQ4y2NgGAW0AzZ2Nv9t7GwkCKljIiD/nJAh+AyQJMYQnAYcOXTkBbIhJBsAtfU5mmtI8gJcM9Q1ZAUiXs2jAAIAZokTkBxhscgAAAAASUVORK5CYII=
/***
|Name|author-control.js|
|Version|1.5|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|Authortools for TiddlyWiki-ebook control functionality of authoring|
!!!!!Revisions
<<<
20131101.0911 ''add'' ''Version 1.5''
* added structure edit for toc
<<<
<<<
20131002.1446 ''add'' ''Version 1.4''
* added information for elementlanguage in sendfunction (if it is given)
<<<
<<<
20131002.1446 ''add'' ''Version 1.3''
* added modelsolution remove
<<<
<<<
20131002.1446 ''fix'' ''Version 1.2''
* fixed cors user-information
<<<
<<<
20131002.1446 ''add'' ''Version 1.1''
* added modelsolution edit mode
20131002.1334 ''add''
* added booktype authorbook to book
<<<
<<<
20130819.1207 ''Version 1.0''
* Fixed lockInAllBook option.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* author-control.js
* Authortools for TiddlyWiki-ebook
* control functionality of authoring
* Petri Salmela
* Petri Sallasmaa
* 8.11.2011
* depends: jQuery, jQueryUI
*******************************************************************/
/************************************************************************
* Booktype authorbook
************************************************************************/
jQuery('body').attr('booktype','authorbook');
/************************************************************************
* Authortool -class
************************************************************************/
function Authortool(callerElem){
if (typeof(callerElem) != 'undefined'){
this.callerElem = callerElem;
}
this.dialogbox;
this.save = function(){};
this.cancel = function(){};
this.bookid = EbookPages[0].ebook.bookid;
this.container = EbookPages[0].currentpage;
this.callFifo = [];
this.sendFifo = [];
this.assignmentlist = false;
}
Authortool.prototype.workingDialog = function(text, title){
if(jQuery('#authordialog_working').length ===0){
this.workingDialogbox = jQuery('body').append('<div id="authordialog_working"></div>').find('#authordialog_working');
this.workingDialogbox.dialog({ //Localization!!
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false,
autoOpen: true,
title: title || EbookDictionary.localize('working'),
close: function(){
jQuery(this).dialog("close").dialog("destroy").remove();
}
});
}
jQuery('#authordialog_working').empty().append('<p class="dialogtext">'+text+'</p>');
}
Authortool.prototype.removeworkingDialog = function(){
config.options.chkAutoSave = true;
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#actionButtons').show();
jQuery('#pageOneNavi').show();
jQuery('#authordialog_working').dialog("destroy").remove();
this.callNext();
}
Authortool.prototype.openDialog = function(dialogid, title, elements){
jQuery('body').append('<div id="authordialog_'+dialogid+'"></div>');
this.dialogbox = jQuery('#authordialog_'+dialogid);
for (var i = 0; i<elements.length; i++){
this.dialogbox.append('<div class="dialogelement '+elements[i]+'"></div>');
}
var tool = this;
this.dialogbox.dialog({
buttons: {
"Cancel": function(){
tool.callFifo = [];
tool.removeLock();
tool.removeLockType();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
jQuery('#pageOneNavi').show();
jQuery(this).dialog("destroy").remove();
},
"Save": function(){if(tool.save()){jQuery('#pageOneNavi').show();jQuery(this).dialog("destroy").remove();}}
}, //Localization!!
width: 1000,
height: 600,
autoOpen: true,
title: title,
close: function(){
jQuery(this).dialog("close").dialog("destroy").remove();
tool.removeLock();
}
});
}
Authortool.prototype.callNext = function(){
var nextf = this.callFifo.shift();
//Debug: what's going on with authormode
// alert(nextf);
if (typeof(nextf) != 'undefined'){
this[nextf]();
}
}
Authortool.prototype.clearCallFifo = function(){
this.callFifo = [];
}
Authortool.prototype.closeDialog = function(dialogid){
jQuery('#authordialog_'+dialogid).dialog('destroy');
}
Authortool.prototype.findFreeTiddler = function(tidprefix){
/********************************************
* Returns next free tiddler name of format: tidprefix_number
********************************************/
tidprefix = EbookPages[0].ebook.bookid + '_' + tidprefix;
var tidnumber = 0;
while (store.tiddlerExists(tidprefix+"_"+tidnumber)){tidnumber=tidnumber+1;}
return tidprefix + '_' + tidnumber;
}
Authortool.prototype.saveTiddler = function(tiddlerName, content, tags, ebooktitle, container, fields){
var tiddler;
if (store.tiddlerExists(tiddlerName)){
tiddler = store.getTiddler(tiddlerName);
} else {
tiddler = store.createTiddler(tiddlerName);
}
for (var i = 0; i<tags.length; i++){
tiddler.tags.pushUnique(tags[i]);
}
fields = fields || tiddler.fields || {};
fields.ebooktitle = ebooktitle;
if (container){
fields.container = container;
}
if(!fields.emathbookid || fields.emathbookid !== EbookPages[0].ebook.bookid){
fields.emathbookid = EbookPages[0].ebook.bookid;
}
var now = new Date();
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now,
tiddler.tags,
tiddler.created,
fields,
config.options.txtUserName);
//autoSaveChanges();
return tiddlerName;
}
Authortool.prototype.refreshTable = function(tnumber){
/******************************************************
* Refresh the nth table.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currenttable = 'table'+tnumber;
var tool = this;
var tdelem = {
'text':'<td><span class="mathquill-textbox tablecell"></span></td>',
'math':'<td><span class="mathquill-editable tablecell"></span></td>'
};
// var tablebody = this.dialogbox.find('.add_table_content table tbody').eq(tnumber);
var tablebody = this.dialogbox.find('.add_table_content.extable_'+tnumber+' table tbody, .questionTablefill[assignmenttable="'+tnumber+'"] table tbody');
tablebody.empty();
for (var i = 0; i<this.tables[currenttable].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables[currenttable].cols; j++){
lasttr.append(tdelem[this.tables[currenttable].types[i][j]]);
lasttr.find('td .mathquill-editable, td .mathquill-textbox').last().append(this.tables[currenttable].data[i][j]);
}
}
tablebody.find('.mathquill-editable').not('.mathquill-rendered-math').mathquill('editable');
tablebody.find('.mathquill-textbox').not('.mathquill-rendered-math').mathquill('textbox');
tablebody.find('.mathquill-editable').focusout(function(){
// var tnumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.add_table_content').eq(0));
var tparent = jQuery(this).parents('.add_table_content');
var tnumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tnumber = parseInt(tnumber);
var cell = jQuery(this);
var value = cell.mathquill('latex');//.replace(/\$([^\$]*)\$/g, '\\($1\\)');
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var tcell = cell.parents('td').eq(0);
var row = ttable.children('tbody').children('tr').index(trow);
var col = trow.children('td').index(tcell);
tool.tables['table'+tnumber].data[row][col] = value;
});
tablebody.parent().attr('class','').addClass(tool.tables['table'+tnumber].class);
}
Authortool.prototype.refreshTableTypes = function(tnumber){
/******************************************************
* Refresh the nth table in "types"-mode.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currenttable = 'table'+tnumber;
var tool = this;
// var tablebody = this.dialogbox.find('.add_table_content table tbody').eq(tnumber);
var tablebody = this.dialogbox.find('.add_table_content.extable_'+tnumber+' table tbody, .questionTablefill[assignmenttable="'+tnumber+'"] table tbody');
tablebody.empty();
for (var i = 0; i<this.tables[currenttable].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables[currenttable].cols; j++){
lasttr.append('<td class="tabletexttype"><span>'+this.tables[currenttable].types[i][j]+'</span></td>');
}
}
tablebody.find('td.tabletexttype').click(function(){
// var tnumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.add_table_content').eq(0));
var tparent = jQuery(this).parents('.add_table_content');
var tnumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tnumber = parseInt(tnumber);
var cell = jQuery(this);
var value = cell.text().toLowerCase();
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var row = parseInt(ttable.children('tbody').children('tr').index(trow));
var col = parseInt(trow.children('td').index(cell));
if (tool.tables['table'+tnumber].data[row][col] == ''){
tool.tables['table'+tnumber]['types'][row][col] = (value == 'text' ? 'math':'text');
tool.refreshTableTypes(tnumber);
} else {
alert('You can only change the type of empty cells.');
}
});
tablebody.parent().attr('class','').addClass(this.tables[currenttable].class);
}
Authortool.prototype.refreshNline = function(nlnumber){
/******************************************************
* Refresh the nth numberline.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currentnline = 'nline'+nlnumber;
var tool = this;
var nlelem = this.dialogbox.find('.add_nline_content').eq(nlnumber).find('.nlinecontainer');
nlelem.empty();
var numline = new EmathbookNumberline();
numline.setdata(this.nlines['nline'+nlnumber]);
numline.create(nlelem);
}
Authortool.prototype.finishAssignmentAuthoring = function(){
/******************************************************
* Finish adding element in chapter/section/subsection
******************************************************/
this.callFifo.push('getUpdates');
this.callFifo.push('saveAssignmentElements');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('removeLockType');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.requestLockType = function(){
/**********************************************
* Request lock type
**********************************************/
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tool = this;
callback = function(data){
if(response.status == 200){
var datanum = parseInt(data);
if (datanum == -1){
if (confirm(EbookDictionary.localize('element locked. wait a minute'))){
return tool.requestLockType();
}else{
jQuery('#pageOneNavi').show();
return false;
}
} else {
tool.containerLockTypeId = datanum;
switch (tool.lockType){
case 'assignment':
tool.finishAssignmentAuthoring();
break;
case 'ebookimage':
tool.finishImageAuthoring();
break;
default:
tool.callNext();
break;
}
}
}else{
alert('check your internetconnection!');
callFifo =[];
if (typeof(tool.dialogbox) != 'undefined'){
tool.dialogbox.dialog('destroy').remove();
}
tool.removeworkingDialog();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
}
}
var sendData = {
"setContainerlock": this.lockType,
"bookName": this.bookid,
"author": config.options.txtUserName,
"username": config.options.txtUserName,
"userkey": config.options.txtUserKey
};
if(typeof(this.lockInAllBook) != "undefined"){
sendData['bookName'] = "lockAll";
}
var response = jQuery.postCORS(updateurl, sendData , callback);
//testilogit.reqlockTyperesp = response;
}
Authortool.prototype.removeLockType = function(){
/**********************************************
* Remove lock type
**********************************************/
var tool = this;
if (typeof(tool.containerLockTypeId) != 'undefined'){
var lockid = tool.containerLockTypeId;
} else {
var lockid = 'all';
}
var tool = this;
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var response = jQuery.postCORS(updateurl,
{
"removeContainerlock":lockid,
"bookName": this.bookid,
"author": config.options.txtUserName,
"username" : config.options.txtUserName,
"userkey" : config.options.txtUserKey,
"container": this.lockType
},
function(){
tool.callNext();
}
);
//testilogit.remlockTyperesp = response;
}
Authortool.prototype.finishImageAuthoring = function(){
/*
* update
* find name
* change name and attach
* send
* remove lock
* end authoring
*/
this.callFifo = [];
this.callFifo.push('getUpdates');
this.callFifo.push('saveImage');
this.callFifo.push('sendContent');
this.callFifo.push('removeLockType');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.saveImage = function(){
// TODO: createAttachmentTiddler to Authortool and add "callNext()" to it.
this.tiddlerName = this.findFreeTiddler(this.elemtype);
this.imagedata.title = this.tiddlerName;
this.imagedata.local = this.imagedata.localpath + this.imagedata.title;
this.createAttachmentTiddler(
this.imagedata.src,
this.imagedata.when,
this.imagedata.notes,
this.imagedata.tags,
this.imagedata.title,
this.imagedata.useData,
this.imagedata.useLocal,
this.imagedata.useUrl,
this.imagedata.local,
this.imagedata.url,
this.imagedata.mimetype,
this.imagedata.imagename,
this.imagedata.author,
this.imagedata.source,
this.imagedata.license,
true);
}
Authortool.prototype.endAuthoring = function(){
/******************************************************
* End authoring (close dialog, refresh,...)
******************************************************/
if (typeof(this.dialogbox) != 'undefined'){
this.dialogbox.dialog('destroy').remove();
}
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
alert('Done!'); //Localization
}
Authortool.prototype.startAuthoring = function(action){
/******************************************************
* Start adding/editing/removing element in chapter/section/subsection
******************************************************/
if (action == undefined){
return false;
}
var loadDialog = jQuery('body').append('<div id="loadBookscreen" title="'+EbookDictionary.localize('initAuthor')+'..."><p class="currentState"></p></div>').find('#loadBookscreen');
loadDialog.dialog({
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false
});
loadDialog.parent().find('.ui-dialog-titlebar-close').remove();
loadDialog.find('p.currentState').text(EbookDictionary.localize('Getting updates'));
this.callFifo.push('getUpdates');
jQuery('#pageOneNavi').hide();
switch (action){
case 'order':
this.callFifo.push('requestLock');
this.callFifo.push('orderElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
break;
case 'makemodelsolution':
this.callFifo.push('requestLock');
this.callFifo.push('makeModelsolution');
break;
case 'editmodelsolution':
this.callFifo.push('requestLock');
this.callFifo.push('editModelsolution');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
this.callFifo.push('removeworkingDialog');
break;
case 'removemodelsolution':
this.callFifo.push('requestLock');
this.callFifo.push('removeModelsolution');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
this.callFifo.push('removeworkingDialog');
break;
case 'edit':
this.callFifo.push('requestLock');
this.callFifo.push('editElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
break;
case 'dictedit':
this.lockType = "dictEdit";
this.specialType = "dictionary";
this.lockInAllBook = "lockAll";
this.callFifo.push('getspecialUpdates');
this.callFifo.push('requestLockType');
this.callFifo.push('editDict');
this.callFifo.push('sendContent');
this.callFifo.push('removeLockType');
break;
case 'tocedit':
this.lockType = "tocEdit";
this.callFifo.push('requestLockType');
this.callFifo.push('editToc');
this.callFifo.push('sendContent');
this.callFifo.push('removeLockType');
this.callFifo.push('getUpdates');
break;
case 'tocstructure':
this.lockType = "tocStructureEdit";
this.callFifo.push('requestLockType');
this.callFifo.push('editTocStructure');
this.callFifo.push('sendContent');
this.callFifo.push('removeLockType');
this.callFifo.push('getUpdates');
this.callFifo.push('removeworkingDialog');
break;
case 'remove':
this.callFifo.push('requestLock');
this.callFifo.push('removeElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
break;
case 'addebooktable':
this.callFifo.push('requestLock');
this.elemtype = 'tableelement';
this.callFifo.push('addElement');
break;
case 'addexamplegeograph':
this.callFifo.push('requestLock');
this.elemtype = 'examplegeograph';
this.callFifo.push('addElement');
break;
case 'addexamplesd':
this.callFifo.push('requestLock');
this.elemtype = 'examplesd';
this.callFifo.push('addElement');
break;
case 'addexample':
this.callFifo.push('requestLock');
this.elemtype = 'examplebox';
this.callFifo.push('addElement');
break;
case 'addtheory':
this.callFifo.push('requestLock');
this.elemtype = 'theorybox';
this.callFifo.push('addElement');
break;
case 'addtext':
this.callFifo.push('requestLock');
this.elemtype = 'textelement';
this.callFifo.push('addElement');
break;
case 'adddiscussion':
this.callFifo.push('requestLock');
this.elemtype = 'discussion';
this.callFifo.push('addElement');
break;
case 'addprerequisites':
this.callFifo.push('requestLock');
this.elemtype = 'prerequisites';
this.callFifo.push('addElement');
break;
case 'addhistory':
this.callFifo.push('requestLock');
this.elemtype = 'history';
this.callFifo.push('addElement');
break;
case 'adddidyouknow':
this.callFifo.push('requestLock');
this.elemtype = 'didyouknow';
this.callFifo.push('addElement');
break;
case 'addotherassignment':
this.callFifo.push('requestLock');
this.elemtype = 'otherassignment';
this.callFifo.push('addOtherassignment');
break;
case 'addassignment':
this.callFifo.push('requestLock');
this.elemtype = 'assignment';
this.callFifo.push('addAssignment');
break;
case 'addimage':
this.elemtype = 'ebookimage';
this.callFifo.push('createImage');
break;
case 'joinimage':
this.callFifo.push('requestLock');
this.elemtype = 'joinimage';
this.callFifo.push('addElement');
break;
case 'copyelement':
jQuery('#pageTwoNavi').hide();
this.callFifo.push('requestLock');
this.elemtype = 'copyelement';
this.callFifo.push('selectCopyElement');
break;
case 'addhint':
case 'addextra':
this.callFifo.push('requestLock');
this.elemtype = action.substr(3);
this.callFifo.push('createsubelement');
break;
default:
this.callFifo.push('endAuthoring');
break;
}
this.callNext();
}
Authortool.prototype.finishAuthoring = function(){
/******************************************************
* Finish adding element in chapter/section/subsection
******************************************************/
this.callFifo.push('getUpdates');
this.callFifo.push('saveNewElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.sendSd = function(){
/******************************************************
* Tool for sending structured derivations
******************************************************/
this.qedelem.find('.qededitorbuttons a.command_qedclose').click();
jQuery('#pageOneNavi').show();
this.callNext();
}
Authortool.prototype.sendGeoeditor = function(){
/******************************************************
* Tool for sending Geoeditor data
******************************************************/
jQuery('#pageOneNavi').show();
this.callNext();
}
Authortool.prototype.getUpdates = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {"updateURL": "", "lastCheck":"0"});
var updateurl = configs.updateURL;
var lastCheck = Emathbook.options.user.updates.lastChecks[this.bookid] || upddata.lastCheck;
var tool = this;
callback = function(data){
//testilogit.authorContentupdate = response;
var loadscreen = jQuery('body #loadBookscreen');
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_'));
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
store.importTiddlyWiki(data);
Emathbook.options.user.updates.lastChecks[tool.bookid] = serverTime;
Emathbook.options.saveUserSettings();
var tocchanged=false;
if(data.match(/tags="[^"]*ebooktoc[^"]*"/)){
//Move to own function????
tocchanged = true;
bookshelf.init();
EbookPages[0].setBook(bookshelf.getBook(EbookPages[0].ebook.bookid));
EbookPages[1].setBook(bookshelf.getBook(EbookPages[1].ebook.bookid));
}
autoSaveChanges();
}
if(loadscreen.length !== 0){
loadscreen.remove();
}
tool.callNext();
}else{
Emathbook.options.netconnection = false;
tool.callFifo=[];
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('no internetconnection'));
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').hide();
setTimeout("jQuery('body').find('#loadBookscreen').remove();",1000);
}
}
}
var sendData = {
"username" : config.options.txtUserName,
"userkey" : config.options.txtUserKey,
"getUpdate":lastCheck,
"bookName": tool.bookid
};
var response = jQuery.postCORS(updateurl, sendData, callback);
}
Authortool.prototype.getspecialUpdates = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {"updateURL": "", "lastCheck":"0"});
var updateurl = configs.updateURL;
var lastCheck = upddata.lastCheck;
var sendData = {
"username":config.options.txtUserName,
"userkey":config.options.txtUserKey
};
var tool = this;
switch(this.specialType){
case 'dictionary':
lastCheck = Emathbook.options.user.updates.lastSysCheck
sendData['getSystemupdates']=lastCheck;
break;
default:
tool.callNext();
}
callback = function(data){
if (response.status == 200){
var serverTime = data.substring(0,data.indexOf('_'));
data = data.substring(data.indexOf('_') + 1);
var updelem = jQuery(data);
var tiddlerDivs = updelem.find('div[title]');
var numberOfUpdates = tiddlerDivs.length;
switch(tool.specialType){
case 'dictionary':
updelem.find('div[title]').not('[tags~="ebdictset"]').remove();
numberOfUpdates = updelem.find('div[title]').length;
break;
default:
tool.callNext();
}
if (numberOfUpdates > 0){
store.importTiddlyWiki(data);
}
tool.callNext();
}else{
Emathbook.options.netconnection = false;
tool.callFifo=[];
alert(EbookDictionary.localize('no internetconnection'));
tool.removeworkingDialog();
}
}
var response = jQuery.postCORS(updateurl, sendData, callback);
}
Authortool.prototype.sendContent = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var senditem = this.sendFifo.shift();
if (typeof(senditem) == 'undefined'){
this.callNext();
return true;
}
if (senditem.system) {
//system update sended to all authorbooks
var system = 1;
} else {
//content update sended to book with same id
var system = 0;
}
if (senditem.system ===2) {
//dictionary update sended to all authorbooks
system = 2;
}
if (senditem.system ===3) {
//modelsolution update sended to book with same id
system = 3;
}
var tiddlerName = senditem.title;
var sendTidller = store.getTiddler(tiddlerName);
var tdata = store.getSaver().externalizeTiddler(store, sendTidller );
var userName = config.options.txtUserName;
var now = new Date();
var nowtime = now.convertToYYYYMMDDHHMMSSMMM()
var data = {
'sendUpdate': nowtime,
'author': userName,
'username' : config.options.txtUserName,
'userkey' : config.options.txtUserKey,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookName': EbookPages[0].ebook.bookid,
'systemUpdate': system
};
if (typeof(senditem.newTiddler) == 'undefined'){
data.newTiddler = '1';
}
if (typeof(sendTidller.fields.elementlanguage) !=="undefined"){
data.elemlanguage = sendTidller.fields.elementlanguage;
}
var tool = this;
var response = jQuery.postCORS(updateurl, data, function(repdata){
//testilogit.resp = repdata;
if (repdata != 'Ok'){
var tiddler = store.getTiddler(tiddlerName);
tiddler.tags.push('notsent');
tiddler.set();
}
tool.sendContent();
});
}
Authortool.prototype.requestLock = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tool = this;
callback = function(data){
if(response.status == 200){
var datanum = parseInt(data);
if (datanum == -1){
alert(EbookDictionary.localize('page locked try later'));
tool.callFifo =[];
if (typeof(tool.dialogbox) != 'undefined'){
tool.dialogbox.dialog('destroy').remove();
}
config.options.chkAutoSave = true;
jQuery('#actionButtons').show();
jQuery('#pageOneNavi').show();
jQuery('#authordialog_working').dialog("destroy").remove();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
} else if (datanum == -2){
alert(EbookDictionary.localize('book locked'));
} else {
tool.containerLockId = datanum;
tool.callNext();
}
}else{
alert('check your internetconnection!');
callFifo =[];
if (typeof(tool.dialogbox) != 'undefined'){
tool.dialogbox.dialog('destroy').remove();
}
tool.removeworkingDialog();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
}
}
var sendData = {
"username" : config.options.txtUserName,
"userkey" : config.options.txtUserKey,
"bookName": tool.bookid,
"setContainerlock":tool.container,
"author": config.options.txtUserName
};
var response = jQuery.postCORS(updateurl, sendData, callback);
//testilogit.lockresp = response;
}
Authortool.prototype.removeLock = function(){
if (typeof(this.containerLockId) != 'undefined'){
var lockid = this.containerLockId;
} else {
var lockid = 'all';
}
var tool = this;
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var sendData = {
"removeContainerlock":lockid,
"bookName": this.bookid,
"author": config.options.txtUserName,
"container": this.container,
"username" : config.options.txtUserName,
"userkey" : config.options.txtUserKey
};
var response = jQuery.postCORS(updateurl, sendData, function(){tool.callNext();});
//testilogit.lockresp = response;
}
Authortool.prototype.emptyf = function(){};
/************************************************************************
* EmathbookAssignnment -class
************************************************************************/
EmathbookAssignnment = function(placeholder, assignmentType, assignmentText){
if (typeof(assignmentType)=="undefined"){
this.assignmentType = -1;
}else{
this.assignmentType = assignmentType;
}
this.data = {"assignmentType": this.assignmentType};
if (typeof(placeholder)=="undefined"){
this.placeHoldertype="lose";
this.placeHolder = "";
}else{
if (store.tiddlerExists(placeholder)){
this.placeHoldertype="tiddler";
} else {
this.placeHoldertype="holder";
}
this.placeHolder = placeholder;
}
if (typeof(assignmentText) =="undefined"){
this.assignmentText = "";
}else{
this.assignmentText = assignmentText;
}
}
_ = EmathbookAssignnment.prototype;
_.setData = function(type,value){
if (typeof(this.data[type])=="undefined" || typeof(this.data[type])=="string"){
this.data[type] = value;
}else if(typeof(this.data[type].pushUnique)=="function"){
this.data[type].push(value);
}else if (this.placeHoldertype == "tiddler"){
this.data = DataTiddler.getDataObject(this.placeHolder);
}
}
_.setText = function(text){
if (typeof(text)=="undefined"){
if (this.placeHoldertype == "tiddler"){
var tiddlerText = store.getTiddler(this.placeHolder).text;
this.assignmentText = tiddlerText.replace(/<data>[^<]*<\/data>/,'');
}
}else{
this.assignmentText = text;
}
}
_.saveToTiddler = function(tiddler){
if (!store.tiddlerExists(tiddler)){
var saveTiddler = store.createTiddler(tiddler);
}else{
var saveTiddler = store.getTiddler(tiddler);
}
saveTiddler.tags.pushUnique('assignment');
saveTiddler.set(tiddler, this.assignmentText+'<data>'+JSON.stringify(this.data)+'</data>',config.options.txtUserName,null,saveTiddler.tags,null,{'emathbookid':EbookPages[0].ebook.bookid},config.options.txtUserName);
}
_.dataString = function (){
return JSON.stringify(this.data);
}
/*********************************************************************
* Actionmenu-class
*********************************************************************/
function Actionmenu(menuname, clickopen, clickclose){
this.menuname = menuname;
this.menuitems = [];
this.clickopen = clickopen;
this.clickclose = clickclose;
var menuid = this.menuname.replace(/[^a-zA-Z0-9]/g,'');
this.menuelement = jQuery('<div id="actionmenu_'+menuid+'" class="actionmenu"><div class="actionmenucontainer"><ul class="actionmenuitemlist"></ul></div><button id="actionbutton_'+menuid+'" class="actionmenubutton"><span>'+menuname+'</span></button></div>');
this.menuelement.find('#actionbutton_'+menuid).button().click({'menu': this, 'clickopen': clickopen, 'clickclose': clickclose},function(e){
var menuchoice = jQuery(this).parents('.actionmenu');
menuchoice.toggleClass('menuopen');
if (menuchoice.hasClass('menuopen') && typeof(e.data.menu.clickopen) == 'function'){
e.data.menu.clickopen();
} else if (typeof(e.data.menu.clickclose) == 'function'){
e.data.menu.clickclose();
}
});
}
Actionmenu.prototype.pushItem = function(item){
var newitem = new ActionmenuItem(item, this);
this.menuitems.push(newitem);
this.menuelement.find('ul.actionmenuitemlist').append(newitem.menuItemElement);
}
Actionmenu.prototype.addMenu = function(addplace){
if(typeof(addplace)=="undefined"){jQuery('#actionButtons .buttonbar .editbuttonset').append(this.menuelement); return true;}
if(typeof(addplace)=="string"){addplace = jQuery(addplace);}
addplace.append(this.menuelement);
}
// Actionmenu.prototype.addMenu = function(){
// jQuery('#actionButtons .buttonbar .editbuttonset').append(this.menuelement);
// }
/*********************************************************************
* ActionmenuItem-class
*********************************************************************/
function ActionmenuItem(menuitem, parent){
this.parent = parent;
if (menuitem == undefined){
menuitem = {};
}
if (menuitem.name != undefined){
this.name = menuitem.name;
} else {
this.name = 'emptyname';
}
if (menuitem.contexts != undefined){
this.contexts = menuitem.contexts;
} else {
this.contexts = ['chapter','section','subsection','frontPage','assignment'];
}
if (menuitem.title != undefined){
this.title = menuitem.title;
} else {
this.title = this.name;
}
if (typeof(menuitem.click) == 'function'){
this.click = menuitem.click;
} else {
this.click = function(){
alert('No action');
}
}
if (menuitem.level != undefined && typeof(menuitem.level) == 'number'){
this.menulevel = menuitem.level
} else {
this.menulevel = 0;
}
var contexts = [];
for (var i = 0; i<this.contexts.length; i++){
contexts.push('context_'+this.contexts[i]);
}
var classes = contexts.concat(['level'+menuitem.level]);
var classesstr = classes.join(' ');
this.menuItemElement = jQuery('<li class="'+classesstr+'"><button class="actionmenuitem_'+this.name+'"><span>'+this.name+'</span></button></li>');
var edata = {'menuitem': this};
this.menuItemElement.find('button').button().click(edata, function(e){
if (e.data.menuitem.menulevel == 1){
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level1').addClass('level2');
} else if (e.data.menuitem.menulevel == 2){
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level2');
} else {
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level1 level2');
}
e.data.menuitem.click();
});
}
//}}}
/*{{{*/
Authortool.prototype.selectCopyElement = function(){
/******************************************************
* Tool for selecting an element to copy from book to another
******************************************************/
var tool = this;
this.assignmentlist = (jQuery('#pageTwo').find('.sdbookassignmentlist').length != 0);
var poneassiglist = (jQuery('#pageOne').find('.sdbookassignmentlist').length != 0);
var pageElements = [];
this.copyElemdata = {"copyelems":[]};
if (!this.assignmentlist && !poneassiglist){
// Not assignment pages
pageElements = jQuery('#pageTwo > [tiddler] > [tiddler]');
var elementType = '[tiddler]';
this.callFifo.push('addElement');
}else if (this.assignmentlist && poneassiglist){
// Assignment pages
var accordions = jQuery('#pageTwo .sdbookassignmentlist .assignmentAccordion0,#pageTwo .sdbookassignmentlist .otherassignmentAccordion');
accordions.accordion( "option", "animated", false );
accordions.find('h3').click();
pageElements = jQuery('#pageTwo .sdbookassignmentlist .assignmentAccordion0 h3,#pageTwo .sdbookassignmentlist .otherassignmentAccordion h3,#pageTwo .sdbookassignmentlist .otherassignmentAccordion li span[tiddler]');
var elementType = 'h3';
this.callFifo.push('copyAssignment');
}
if (pageElements.length == 0){
jQuery('#pageTwoNavi').show();
alert('Nothing to copy.'); //Localization
tool.callFifo = [];
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
return false;
}
setTimeout("jQuery('#pageTwo > [tiddler]').addClass('copyelems');",30);
if (!this.assignmentlist){
pageElements.append('<div class="copythis"><a href="javascript:;" title="Copy this element"><span>Copy</span></a></div>')
.find('.copythis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).addClass('selectedforcopy').attr('tiddler');
jQuery('.copythis').remove();
jQuery('.copyelems').removeClass('copyelems');
tool.callNext();
});
} else {
pageElements.append('<div class="copythis"><a href="javascript:;" title="Copy this element"><span>Copy</span></a></div>')
.find('.copythis a').click(function(){
var parent = jQuery(this).parents(elementType).eq(0);
if (parent.hasClass('selectedforcopy')){
tool.copyElemdata.copyelems.remove(parent.attr('tiddler'));
parent.removeClass('selectedforcopy');
} else {
parent.addClass('selectedforcopy');
tool.copyElemdata.copyelems.push(parent.attr('tiddler'));
}
return false;
});
}
}
Authortool.prototype.getRecursiveElements = function(tiddlerName){
/******************************************************
* Tool for finding names of tiddlers of elements recursively.
******************************************************/
tiddlerName = tiddlerName || this.tiddlerName;
if (!tiddlerName){
return [];
}
var text = store.getTiddlerText(tiddlerName);
var rex = new RegExp('(?:<<(?:ebookbox|ebooktable|ebookgraph) \\[\\[([^\\]]*)\\]\\].*>>|\!image\n\\[img\\[([^\\]]*)\\]\\]|<<showAssignment ([^>]+)>>)','g');
var reflist = [];
var ref;
while (ref = rex.exec(text)){
var item = ref[1] || ref[2] || ref[3];
if (reflist.indexOf(item) == -1){
reflist.push(item);
}
}
var tiddlernames = [tiddlerName];
for (var i = 0; i<reflist.length; i++){
tiddlernames = tiddlernames.concat(this.getRecursiveElements(reflist[i]));
}
var relatedTiddlers = store.reverseLookup('container', tiddlerName, true);
for (var i = 0; i<relatedTiddlers.length; i++){
tiddlernames.push(relatedTiddlers[i].title);
}
var relatedTiddlers = store.reverseLookup('translation', tiddlerName, true);
for (var i = 0; i<relatedTiddlers.length; i++){
tiddlernames.push(relatedTiddlers[i].title);
}
// Temporary fix for missing translation fields. TODO: remove when not needed anymore.
var trans = ['_fi', '_sv', '_et'];
for (var i = 0; i<3; i++){
if (store.tiddlerExists(tiddlerName + trans[i])){
tiddlernames.push(tiddlerName + trans[i]);
var ttt = store.getTiddler(tiddlerName + trans[i]);
if (!ttt.fields.translation){
ttt.fields.translation = tiddlerName;
ttt.set();
}
}
}
// Temporary fix ends.
jQuery('.selectedforcopy').removeClass('selectedforcopy');
var allTiddlers = [];
for (var i = 0; i<tiddlernames.length; i++){
if (allTiddlers.indexOf(tiddlernames[i]) == -1){
allTiddlers.push(tiddlernames[i]);
}
}
return allTiddlers;
}
Authortool.prototype.copyElement = function(){
/******************************************************
* Tool for copying an element from book to another
******************************************************/
this.copydata = {};
this.copydata.fromtiddlers = this.getRecursiveElements();
this.copydata.newnames = {};
this.lockType = EbookPages[0].ebook.bookid;
this.callFifo.push('requestLockType');
this.callFifo.push('getUpdates');
this.callFifo.push('copyElementsDo');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('removeLockType');
this.callFifo.push('endCopying');
this.callNext();
}
Authortool.prototype.copyElementsDo = function(){
/******************************************************
* Tool for copying an element from book to another
* The actual copying
******************************************************/
this.copydata.istranslation = {};
for (var i = 0; i<this.copydata.fromtiddlers.length; i++){
var tname = this.copydata.fromtiddlers[i];
if (!tname.match(/_[a-z]+$/)){
this.copydata.newnames[tname] = this.findFreeTiddler(tname.match(/^(?:[0-9]+_)?([a-z]+)_[0-9]+/)[1]);
this.copydata.istranslation[tname] = false;
} else {
var container = tname.match(/^(?:[0-9]+_)?[a-z]+_[0-9]+/);
this.copydata.newnames[tname] = tname.replace(container, this.copydata.newnames[container]);
var langrex = new RegExp('_'+Emathbook.options.pages[0].defaultlang + '$');
if (this.copydata.newnames[tname].match(/_data$/)
&& (Emathbook.options.pages[0].defaultlang != Emathbook.options.pages[1].defaultlang)){
this.copydata.newnames[tname] += ('_'+ Emathbook.options.pages[1].defaultlang);
this.copydata.istranslation[tname] = container;
} else if (Emathbook.options.pages[0].defaultlang != Emathbook.options.pages[1].defaultlang){
this.copydata.newnames[tname] = this.copydata.newnames[tname].replace(langrex, '');
var oldtiddler = store.getTiddler(tname);
this.copydata.istranslation[tname] = (oldtiddler.fields && oldtiddler.fields.translation &&!(tname.match(langrex)) && container);
} else {
var oldtiddler = store.getTiddler(tname);
this.copydata.istranslation[tname] = (oldtiddler.fields && oldtiddler.fields.translation && container);
}
}
store.createTiddler(this.copydata.newnames[tname]);
}
for (var i = 0; i<this.copydata.fromtiddlers.length; i++){
var fromname = this.copydata.fromtiddlers[i];
var toname = this.copydata.newnames[fromname];
var content = store.getTiddlerText(fromname);
for (var j = 0; j<this.copydata.fromtiddlers.length; j++){
var tname = this.copydata.fromtiddlers[j];
if (tname.match(/_data$/)){
continue;
}
var tnrex = new RegExp(tname, 'g');
content = content.replace(tnrex, this.copydata.newnames[tname]);
}
var oldtiddler = store.getTiddler(fromname);
var tags = oldtiddler.tags;
var ebooktitle = oldtiddler.fields ? oldtiddler.fields.ebooktitle : '';
var fields = {};
jQuery.extend(fields, oldtiddler.fields);
var container = (oldtiddler.fields && oldtiddler.fields.container) ? this.copydata.newnames[oldtiddler.fields.container] || '' : '';
var translation = (this.copydata.istranslation[fromname]) ? this.copydata.newnames[this.copydata.istranslation[fromname]] || '' : '';
fields.container = container;
fields.translation = translation;
this.saveTiddler(toname, content, tags, ebooktitle, container, fields);
this.sendFifo.push({"title": toname, "newTiddler": 1});
}
this.tiddlerName = this.copydata.newnames[this.tiddlerName];
this.addInTiddler();
this.callNext();
}
Authortool.prototype.endCopying = function(){
/******************************************************
* End copy action. (Close menu.)
******************************************************/
jQuery('#pageOneNavi').show();
jQuery('#pageTwoNavi').show();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
}
Authortool.prototype.copyAssignment = function(){
/******************************************************
* Copy assignments from one book to another.
* Start copying.
******************************************************/
this.copydata = {};
this.copydata.fromass = [];
this.copydata.fromoass = [];
for (var i = 0; i<this.copyElemdata.copyelems.length; i++){
if (this.copyElemdata.copyelems[i].match(/^(?:[0-9]+_)?assignment_/)){
this.copydata.fromass.push(this.copyElemdata.copyelems[i]);
} else if (this.copyElemdata.copyelems[i].match(/^(?:[0-9]+_)?otherassignment_/)){
this.copydata.fromoass.push(this.copyElemdata.copyelems[i]);
}
}
this.copydata.newnames = {};
this.lockType = EbookPages[0].ebook.bookid;
this.callFifo.push('requestLockType');
this.callFifo.push('getUpdates');
this.callFifo.push('copyAssignmentsDo');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('removeLockType');
this.callFifo.push('endCopying');
this.callNext();
}
Authortool.prototype.copyAssignmentsDo = function(){
/******************************************************
* Copy assignments from one book to another.
* The actual copying.
******************************************************/
var alistTiddlerName = jQuery('#pageOne .ebookbox .sdbookassignmentlist [tiddler]').eq(0).attr('tiddler');
var alistTiddler = store.getTiddler(alistTiddlerName);
var atiddlers = [];
var oatiddlers = [];
var fromassnames = [];
var newnames = {};
var newbasenames = {};
var istranslation = {};
for (var i = 0; i<this.copydata.fromass.length; i++){
if (Emathbook.options.pages[0].defaultlang != Emathbook.options.pages[1].defaultlang && !store.tiddlerExists(this.copydata.fromass[i] + '_' + Emathbook.options.pages[0].defaultlang)){
alert(EbookDictionary.localize('can not copy') + '\n' + jQuery('#pageTwo h3[tiddler="'+this.copydata.fromass[i]+'"]').text().replace(/Copy$/,'') + '\n'+EbookDictionary.localize('not yet translated'));
continue;
}
var deps = this.getRecursiveElements(this.copydata.fromass[i]);
for (var j = 0; j<deps.length; j++){
if (atiddlers.indexOf(deps[j] == -1)){
atiddlers.push(deps[j]);
var basename = deps[j].match(/^(?:[0-9]*_)?(?:[a-z]+)_[0-9]+/)[0];
var tiddlertype = basename.match(/(?:[0-9]*_)?([a-z_]+)_[0-9]+/)[1];
var extension = deps[j].match(/_([a-z]+)$/);
extension = (extension && extension[1]) || '';
if (!newbasenames[basename]){
newbasenames[basename] = this.findFreeTiddler(tiddlertype);
store.createTiddler(newbasenames[basename]);
}
if (deps[j] == basename && tiddlertype == 'assignment'){
fromassnames.push(basename);
if (Emathbook.options.pages[0].defaultlang == Emathbook.options.pages[1].defaultlang){
newnames[deps[j]] = newbasenames[basename];
istranslation[deps[j]] = false;
} else {
newnames[deps[j]] = newbasenames[basename] + '_' + Emathbook.options.pages[1].defaultlang;
istranslation[deps[j]] = basename;
}
} else if (tiddlertype == 'assignment') {
if (Emathbook.options.pages[0].defaultlang == Emathbook.options.pages[1].defaultlang){
newnames[deps[j]] = newbasenames[basename] + '_' + extension;
istranslation[deps[j]] = basename;
} else {
if (extension == Emathbook.options.pages[0].defaultlang){
newnames[deps[j]] = newbasenames[basename];
istranslation[deps[j]] = false;
} else {
newnames[deps[j]] = newbasenames[basename] + '_' + extension;
istranslation[deps[j]] = basename;
}
}
} else {
newnames[deps[j]] = newbasenames[basename];
istranslation[deps[j]] = false;
}
}
}
}
for (var i = 0; i<this.copydata.fromoass.length; i++){
var odeps = this.getRecursiveElements(this.copydata.fromoass[i]);
for (var j = 0; j<odeps.length; j++){
if (oatiddlers.indexOf(odeps[j] == -1)){
oatiddlers.push(odeps[j]);
newnames[odeps[j]] = this.findFreeTiddler(odeps[j].match(/(?:[0-9]*_)?([a-z_]+)_[0-9]+/)[1]);
store.createTiddler(newnames[odeps[j]]);
}
}
}
for (var i = 0; i<atiddlers.length; i++){
var fromname = atiddlers[i];
var toname = newnames[fromname];
var content = store.getTiddlerText(fromname);
for (var bname in newbasenames){
var tnrex = new RegExp(bname, 'g');
content = content.replace(tnrex, newbasenames[bname]);
}
var oldtiddler = store.getTiddler(fromname);
var tags = oldtiddler.tags;
var ebooktitle = oldtiddler.fields ? oldtiddler.fields.ebooktitle : '';
var container = (oldtiddler.fields && oldtiddler.fields.container) ? newnames[oldtiddler.fields.container] || '' : '';
var translation = (istranslation[fromname]) ? newbasenames[istranslation[fromname]] || '' : '';
var fields = {};
jQuery.extend(fields, oldtiddler.fields);
fields.container = container;
fields.translation = translation;
fields.copiedfrom = (fields.copiedfrom && (fields.copiedfrom + ' ' + fromname ))|| fromname;
this.saveTiddler(toname, content, tags, ebooktitle, container, fields);
this.sendFifo.push({"title": toname, "newTiddler": 1});
}
for (var i = 0; i<oatiddlers.length; i++){
var fromname = oatiddlers[i];
var toname = newnames[fromname];
var content = store.getTiddlerText(fromname);
for (var j = 0; j<oatiddlers.length; j++){
var tname = oatiddlers[j];
if (tname.match(/_data$/)){
continue;
}
var tnrex = new RegExp(tname, 'g');
content = content.replace(tnrex, newnames[tname]);
}
var oldtiddler = store.getTiddler(fromname);
var tags = oldtiddler.tags;
var ebooktitle = oldtiddler.fields ? oldtiddler.fields.ebooktitle : '';
var container = (oldtiddler.fields && oldtiddler.fields.container) ? this.copydata.newnames[oldtiddler.fields.container] || '' : '';
this.saveTiddler(toname, content, tags, ebooktitle, container);
this.sendFifo.push({"title": toname, "newTiddler": 1});
}
var alcontent = alistTiddler.text;
for (var i = 0; i<fromassnames.length; i++){
alcontent = alcontent.replace(/(<<assignmentAccordion[^>]*)>>/,'$1 '+newbasenames[fromassnames[i]]+'>>');
}
for (var i = 0; i<this.copydata.fromoass.length; i++){
alcontent = alcontent.replace(/(<<otherassignmentAccordion[^>]*)>>/,'$1 '+newnames[this.copydata.fromoass[i]]+'>>');
}
this.saveTiddler(alistTiddler.title, alcontent, alistTiddler.tags, alistTiddler.ebooktitle, alistTiddler.container);
this.sendFifo.push({"title": alistTiddler.title, "newTiddler": 0});
this.callNext();
}
/*}}}*/
/***
|Name|author-createAdd.js|
|Version|1.5|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|Authortools for TiddlyWiki-ebook fuctionality for adding staff to ebook|
!!!!!Revisions
<<<
20131710.1544 ''fix'' ''Version 1.5''
* Fixed blocked extra/hint add for additional language
<<<
<<<
20131710.1544 ''add'' ''Version 1.4''
* Added titleinput to extra/hint boxes
<<<
<<<
20131710.1544 ''fix'' ''Version 1.3''
* Copy of modelsolution language change fix
<<<
<<<
20131010.0914 ''add'' ''Version 1.2''
* Copy of modelsolution added
<<<
<<<
20131010.0914 ''add'' ''Version 1.1''
* Make of modelsolution added
<<<
<<<
20130820.1140 ''add'' ''Version 1.0''
* signchart added.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* author-createAdd.js
* Authortools for TiddlyWiki-ebook
* to add or create elements
* Petri Salmela
* Petri Sallasmaa
* 8.11.2011
* depends: jQuery, jQueryUI
*******************************************************************/
Authortool.prototype.makeModelsolution = function(){
/******************************************************
* Tool for creating a new subsection
******************************************************/
if(store.reverseLookup('modelsolutionto',this.assignmentTiddler, true, 'created').length > this.solutions_length){
alert(EbookDictionary.localize('modelsolution add to this'));
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#pageOne h3[tiddler="'+this.assignmentTiddler+'"]').click();
jQuery('#pageOneWrapper').scrollTop(this.scroll);
this.callFifo.push('removeLock');
this.callNext();
}else{
var saveStatus= config.options.chkAutoSave;
config.options.chkAutoSave = false;
var newmodel = store.createTiddler('creatingModelsolution');
if(typeof(this.copymodelsolution) !=="undefined"){
var oldmodel = store.getTiddler(this.tiddlerName)
newmodel.set(null,oldmodel.text,config.options.txtUserName,null,oldmodel.tags,null,JSON.parse(JSON.stringify(oldmodel.fields)),config.options.txtUserName);
var tiddlerData = DataTiddler.getData(newmodel,'modelsolution');
tiddlerData.editable = true;
DataTiddler.setData(newmodel,'modelsolution',tiddlerData);
}else{
var setfields = {"emathbookid":EbookPages[0].ebook.bookid,"modelsolutionto":this.assignmentTiddler,"elementlanguage":EbookPages[0].currentlang, "modelpage" :EbookPages[0].ebook.getContentById(this.container)};
var settext = "<<modelsolution>>\n<data>{\"modelsolution\":{\"creator\":\""+(config.options.txtModelsolutionCreator || 'Emath')+"\",\"modelsolutionAnswer\":\"\",\"editable\":true,\"ispublic\":false,\"elemtype\":\"modelsolution\",\"modelsolutionelements\":[]}}</data>";
newmodel.set(null,settext,null,null,['modelsolution'],null,setfields);
}
config.options.chkAutoSave = saveStatus;
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#pageOne h3[tiddler="'+this.assignmentTiddler+'"]').click();
jQuery('#pageOne h3').unbind('click');
jQuery('#pageOneWrapper').scrollTop(this.scroll);
}
}
Authortool.prototype.createSubsection = function(){
/******************************************************
* Tool for creating a new subsection
******************************************************/
this.tiddlerName = this.findFreeTiddler('subsection');
this.openDialog('addsubsection', 'Create new subsection', ['add_ebook_title', 'tag_insert']); // Localization
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.add_ebook_title').append('<h1>Subsection title:</h1><input type="text" class="add_ebook_title"/>');
this.save = function(){
var Ebook_title = this.dialogbox.find('input.add_ebook_title').val();
var subsecdata = {
'ebooktitle': Ebook_title,
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': ''
}
subsecdata.tags.push('subsection');
subsecdata.tags.push('container');
if (Ebook_title != ''){
subsecdata['content'] = '!!'+Ebook_title+'\n';
}
this.saveTiddler(this.tiddlerName, subsecdata.content, subsecdata.tags, subsecdata.ebooktitle);
return true;
}
return this.tiddlerName;
}
Authortool.prototype.pageComment = function(){
/******************************************************
* Tool for creating a comment
******************************************************/
this.commentto = EbookPages[0].ebook.tocdict[EbookPages[0].currentpage].content;
this.tiddlerName = this.commentto + '_comment_'+config.options.txtUserName;
var commenttext = '';
var commentdata = {};
var commenttags = ['pagecomment'];
var tool = this;
if (store.tiddlerExists(this.tiddlerName)){
commenttext = store.getTiddlerText(this.tiddlerName).replace(/\n*<data>.*<\/data>\n*/,'');
commentdata = DataTiddler.getData(this.tiddlerName, 'pagecomments', {});
}
this.oldcommenttext = commenttext;
this.oldcommentdata = JSON.stringify(commentdata);
var ctypes = ['content','system','layout'];
for (var i = 0; i<ctypes.length; i++){
commentdata[ctypes[i]] = commentdata[ctypes[i]] || {'text':'','date':''};
}
this.openDialog('pagecomment', 'Comment this page', ['chk_sendserver','commenttype','pagecomment']); // Localization
this.dialogbox.dialog('option','width',jQuery('body').width() /2);
this.dialogbox.dialog('option','position',['right','center']);
this.dialogbox.find('.pagecomment').append('<h1>My comment:</h1><textarea id="mypagecomment" name="mypagecomment" style="width: 100%;height:20em;">'+commenttext+'</textarea>');
this.dialogbox.find('.chk_sendserver').append('<label for="chksendcomment">Send comment to the server</label><input id="chksendcomment" checked="checked" type="checkbox" />');
this.selectedtype = 'general';
this.dialogbox.find('.commenttype').append('<h2>Comment type</h2><input name="commenttype" type="radio" value="general" checked="checked">General</input><input name="commenttype" type="radio" value="content">Content</input><input name="commenttype" type="radio" value="system">System</input><input name="commenttype" type="radio" value="layout">Layout</input>')
.find('input[name="commenttype"]').click(function(){
if (tool.selectedtype == 'general'){
commenttext = tool.dialogbox.find('.pagecomment textarea#mypagecomment').val();
} else {
commentdata[tool.selectedtype].text = tool.dialogbox.find('.pagecomment textarea#mypagecomment').val();
commentdata[tool.selectedtype].date = (new Date()).toString();
}
tool.selectedtype = jQuery(this).val();
if (tool.selectedtype == 'general'){
tool.dialogbox.find('.pagecomment textarea#mypagecomment').val(commenttext);
} else {
tool.dialogbox.find('.pagecomment textarea#mypagecomment').val(commentdata[tool.selectedtype].text);
}
});
this.save = function(){
tool.dialogbox.find('.commenttype input[name="commenttype"]:checked').click();
if(store.tiddlerExists(tool.tiddlerName) && tool.oldcommenttext !== commenttext){
store.getTiddler(tool.tiddlerName).tags = ['pagecomment'];
}
var comparedata = JSON.parse(tool.oldcommentdata);
for (var commtype in commentdata){
if(typeof(comparedata[commtype]) === 'undefined' || comparedata[commtype].text !== commentdata[commtype].text){
commentdata[commtype].hidden = 'show';
}
}
var allcommentdata = {
'content': commenttext + '\n<data>{"pagecomments":' + JSON.stringify(commentdata) + '}</data>',
'tags': commenttags
}
this.saveTiddler(this.tiddlerName, allcommentdata.content, allcommentdata.tags, '',null, {"commentto": tool.commentto,"authorcommenttoid": EbookPages[0].ebook.bookid});
if (this.dialogbox.find('#chksendcomment').attr('checked')){
Emathbook.sendPageComment(this.tiddlerName);
}
refreshElements(jQuery('#pageTwo')[0]);
return true;
}
return this.tiddlerName;
}
Authortool.prototype.joinImageElement = function(){
/******************************************************
* Tool for joining preAttached image to the book
******************************************************/
this.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
var tool = this;
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input class="x_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input class="y_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" checked="checked" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var allimages = store.getTaggedTiddlers('looseImage');
var selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li').eq(0).addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imageTiddlers[0].title+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
this.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
switch(jQuery(event.target).text()){
case 'Not fixed images':
allimages = store.getTaggedTiddlers('looseImage');
selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
break;
case 'All images':
allimages = store.getTaggedTiddlers('ebookimage');
selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
break;
case 'Choice tag':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
default:
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
}
initImageList(selectedImageTiddlers);
});
this.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+this.dialogbox.find('.x_size input.x_size_input').val()+"\n!size-y\n"+this.dialogbox.find('.y_size input.y_size_input').val();
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookgraph [[tiddlernameplaceholder]] image>>'
}
this.elementcont.tags.push('ebookgraph_image');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),
'content': content
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createGeograph = function(){
this.finishAuthoring();
return true;
}
Authortool.prototype.createSd = function(){
/******************************************************
* Tool for creating a new empty SD (inside examplebox).
******************************************************/
this.elementcont = {
'ebooktitle': '',
'tags': ['examplesd'],
'content': '<<ebookbox [[tiddlernameplaceholder_data]] examplesd>>'
}
this.elementcont.tags.push('examplebox');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['examplebox','data','examplesd'],
'content': '<<qedderiv examplesd0 savehere>>',
'data': {}
}
this.finishAuthoring();
return true;
}
Authortool.prototype.addSignchartClick = function(e){
var elementType = e.data.createType;
var addexelem = jQuery('#authordialog_add'+elementType+'box').find('.add_'+elementType+'_elem');
var chartnum = addexelem.find('.add_'+elementType+'_signchart').length;
addexelem.append('<div><div class="'+elementType+'_elem add_'+elementType+'_signchart '+elementType+'_signchart_'+chartnum+'"></div></div>');
wikify('<<pssignchart '+elementType+'signC'+chartnum+' authordialog>>', addexelem.find('.add_'+elementType+'_signchart.'+elementType+'_signchart_'+chartnum)[0]);
}
Authortool.prototype.createExample = function(){
/******************************************************
* Tool for creating a new examplebox
******************************************************/
var tool = this;
this.createType = "example";
this.openDialog('addexamplebox', 'Create new example', ['add_example_head', 'tag_insert', 'add_example_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_example_head')
.append('<h2>Example header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_example_elem')
.append('<h2>Example content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_derivation_button">Derivation</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button><button class="add_signchart_button">Signchart</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem').append('<div><textarea class="example_elem add_example_text"></textarea></div>');
}).end()
.find('.add_signchart_button').click({"createType":tool.createType},tool.addSignchartClick).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem').append('<div class="mathdisplaystyle"><span class="example_elem add_example_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_derivation_button').click(function(){
var addexelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var sdnum = addexelem.find('.add_example_deriv').length;
addexelem.append('<div><div class="example_elem add_example_deriv exderiv_'+sdnum+'"></div></div>');
wikify('<<qedderiv examplesd'+sdnum+'>>', addexelem.find('.add_example_deriv.exderiv_'+sdnum)[0]);
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var geoeditornum = addelem.find('.add_example_geoeditor').length;
addelem.append('<div><div class="example_elem add_example_geoeditor exgeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph examplegeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_example_geoeditor.exgeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_graph_button').click(function(){
var addexelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var funcgnro = addexelem.find('.add_example_funcgraph').length;
addexelem.append('<div><div class="example_elem add_example_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addexelem.find('.add_example_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
addelem.append('<div><div class="example_elem add_example_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_example_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){
var addexelem = jQuery('#authordialog_addexamplebox').find('.add_example_elem');
var tablenro = addexelem.find('.add_example_table').length;
addexelem.append('<div><div class="example_elem add_example_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addexelem.find('.add_example_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="example_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_example_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();// Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] example>>'
}
this.elementcont.tags.push('examplebox');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['examplebox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_example_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var elements = this.dialogbox.find('.example_elem');
var examplederiv_number = 0;
var examplegeoeditor_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_example_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_example_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_example_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph examplegeoeditor'+examplegeoeditor_number+' '+sizeParam+'>>\n'
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['examplegeoeditor'+examplegeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
examplegeoeditor_number++;
} else if (elements.eq(i).hasClass('add_example_deriv')){
this.elementdata.content += '<<qedderiv examplesd'+examplederiv_number+' savehere>>\n';
if (typeof(this.elementdata.data.derivations) == 'undefined'){
this.elementdata.data.derivations = {};
}
var exsdeditor = elements.eq(i).find('.qededitor')[0].editor;
var derdata = exsdeditor.derivation.getSaveData();
for (var j=0; j<derdata.length; j++){
this.elementdata.data.derivations[derdata[j].name] = derdata[j].data;
exsdeditor.deleteDeriv(derdata[j].name);
}
examplederiv_number++;
}else if (elements.eq(i).hasClass('add_'+tool.createType+'_signchart')){
if(!signchartcount){
var signchartcount = 0;
}
this.elementdata.content += '<<pssignchart '+tool.createType+'signC'+signchartcount+'>>\n';
if (typeof(this.elementdata.data.signchart) == 'undefined'){
this.elementdata.data.signchart = {};
}
this.elementdata.data.signchart[tool.createType+'signC'+signchartcount] = elements.eq(i).find('.pssc.pssc_'+tool.createType+'signC'+signchartcount).pssignchart('get');
signchartcount++;
} else if (elements.eq(i).hasClass('add_example_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_example_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_example_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createTextelement = function(){
/******************************************************
* Tool for creating a new newkindof textelement
******************************************************/
var tool = this;
this.createType ="textelement";
this.openDialog('addtextelementbox', 'Create new textelement', [ 'add_textelement_elem','tag_insert', 'add_button_bar']); // Localization
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_textelement_elem')
.append('<h2>textelement content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_derivation_button">Derivation</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button><button class="add_signchart_button">Signchart</button> </div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem').append('<div><textarea class="textelement_elem add_textelement_text"></textarea></div>');
}).end()
.find('.add_signchart_button').click({"createType":tool.createType},tool.addSignchartClick).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem').append('<div class="mathdisplaystyle"><span class="textelement_elem add_textelement_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_derivation_button').click(function(){
var addexelem = jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem');
var sdnum = addexelem.find('.add_textelement_deriv').length;
addexelem.append('<div><div class="textelement_elem add_textelement_deriv textelementderiv_'+sdnum+'"></div></div>');
wikify('<<qedderiv textelementsd'+sdnum+'>>', addexelem.find('.add_textelement_deriv.textelementderiv_'+sdnum)[0]);
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem');
var geoeditornum = addelem.find('.add_textelement_geoeditor').length;
addelem.append('<div><div class="textelement_elem add_textelement_geoeditor textelementgeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph textelementgeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_textelement_geoeditor.textelementgeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem');
var funcgnro = addelem.find('.add_textelement_funcgraph').length;
addelem.append('<div><div class="textelement_elem add_textelement_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_textelement_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem');
addelem.append('<div><div class="textelement_elem add_textelement_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_textelement_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){
var addelem = jQuery('#authordialog_addtextelementbox').find('.add_textelement_elem');
var tablenro = addelem.find('.add_textelement_table').length;
addelem.append('<div><div class="textelement_elem add_textelement_table texttable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_textelement_table.texttable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtextelementbox').find('.add_textelement_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="textelement_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_textelement_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();// Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] textelement>>'
}
this.elementcont.tags.push('textelementbox');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['textelementbox','data'],
'content': '',
'data': {}
}
//this.elementdata.content += '!' + this.dialogbox.find('.add_textelement_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var elements = this.dialogbox.find('.textelement_elem');
var textelementderiv_number = 0;
var textelementgeoeditor_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_textelement_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_textelement_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_'+tool.createType+'_signchart')){
if(!signchartcount){var signchartcount=0;}
this.elementdata.content += '<<pssignchart '+tool.createType+'signC'+signchartcount+'>>\n';
if (typeof(this.elementdata.data.signchart) == 'undefined'){
this.elementdata.data.signchart = {};
}
this.elementdata.data.signchart[tool.createType+'signC'+signchartcount] = elements.eq(i).find('.pssc.pssc_'+tool.createType+'signC'+signchartcount).pssignchart('get');
signchartcount++;
} else if (elements.eq(i).hasClass('add_textelement_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph textelementgeoeditor'+textelementgeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['textelementgeoeditor'+textelementgeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
textelementgeoeditor_number++;
} else if (elements.eq(i).hasClass('add_textelement_deriv')){
this.elementdata.content += '<<qedderiv textelementsd'+textelementderiv_number+' savehere>>\n';
if (typeof(this.elementdata.data.derivations) == 'undefined'){
this.elementdata.data.derivations = {};
}
var exsdeditor = elements.eq(i).find('.qededitor')[0].editor;
var derdata = exsdeditor.derivation.getSaveData();
for (var j=0; j<derdata.length; j++){
this.elementdata.data.derivations[derdata[j].name] = derdata[j].data;
exsdeditor.deleteDeriv(derdata[j].name);
}
textelementderiv_number++;
} else if (elements.eq(i).hasClass('add_textelement_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_textelement_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_textelement_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createTheory = function(){
/******************************************************
* Tool for creating a new theorybox
* TODO: combine more with createExample
******************************************************/
var tool = this;
this.createType = "theory";
this.tiddlerName = this.findFreeTiddler('theorybox');
this.openDialog('addtheorybox', 'Create new theory', ['add_theory_head', 'tag_insert', 'add_theory_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_theory_head')
.append('<h2>Theorybox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_theory_elem')
.append('<h2>Theorybox content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button><button class="add_signchart_button">Signchart</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem').append('<div><textarea class="theory_elem add_theory_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem').append('<div class="mathdisplaystyle"><span class="theory_elem add_theory_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
var geoeditornum = addelem.find('.add_theory_geoeditor').length;
addelem.append('<div><div class="theory_elem add_theory_geoeditor theorygeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph theorygeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_theory_geoeditor.theorygeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
var funcgnro = addelem.find('.add_theory_funcgraph').length;
addelem.append('<div><div class="theory_elem add_theory_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_theory_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
addelem.append('<div><div class="theory_elem add_theory_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_theory_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){
var addelem = jQuery('#authordialog_addtheorybox').find('.add_theory_elem');
var tablenro = addelem.find('.add_theory_table').length;
addelem.append('<div><div class="theory_elem add_theory_table thorytable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_theory_table.thorytable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="theory_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_theory_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.find('.add_signchart_button').click({"createType":tool.createType},tool.addSignchartClick).end()
.buttonset(); // Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] theory>>'
}
this.elementcont.tags.push('theorybox');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['theorybox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_theory_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var examplegeoeditor_number = 0;
var elements = this.dialogbox.find('.theory_elem');
var theoryderiv_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_theory_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_'+tool.createType+'_signchart')){
if(!signchartcount){var signchartcount=0;}
this.elementdata.content += '<<pssignchart '+tool.createType+'signC'+signchartcount+'>>\n';
if (typeof(this.elementdata.data.signchart) == 'undefined'){
this.elementdata.data.signchart = {};
}
this.elementdata.data.signchart[tool.createType+'signC'+signchartcount] = elements.eq(i).find('.pssc.pssc_'+tool.createType+'signC'+signchartcount).pssignchart('get');
signchartcount++;
} else if (elements.eq(i).hasClass('add_theory_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_theory_deriv')){
this.elementdata.content += '<<qedderiv theorysd'+theoryderiv_number+' savehere>>\n';
theoryderiv_number++;
} else if (elements.eq(i).hasClass('add_theory_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph theorygeoeditor'+examplegeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['theorygeoeditor'+examplegeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
examplegeoeditor_number++;
} else if (elements.eq(i).hasClass('add_theory_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_theory_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_theory_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createDidYouKnow = function(){
/******************************************************
* Tool for creating a new Did you know box
* TODO: combine more with createExample
******************************************************/
var tool = this;
this.tiddlerName = this.findFreeTiddler('didyouknow');
this.openDialog('adddidyouknowbox', 'Create new Did you know', ['add_didyouknow_head', 'tag_insert', 'add_didyouknow_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_didyouknow_head')
.append('<h2>Header for did you know:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_didyouknow_elem')
.append('<h2>Did you know box content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem').append('<div><textarea class="didyouknow_elem add_didyouknow_text"></textarea></div>');
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem');
var geoeditornum = addelem.find('.add_didyouknow_geoeditor').length;
addelem.append('<div><div class="didyouknow_elem add_didyouknow_geoeditor didyouknowgeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph didyouknowgeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_didyouknow_geoeditor.didyouknowgeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem').append('<div class="mathdisplaystyle"><span class="didyouknow_elem add_didyouknow_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem');
var funcgnro = addelem.find('.add_didyouknow_funcgraph').length;
addelem.append('<div><div class="didyouknow_elem add_didyouknow_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_didyouknow_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem');
addelem.append('<div><div class="didyouknow_elem add_didyouknow_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_didyouknow_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem');
var tablenro = addelem.find('.add_didyouknow_table').length;
addelem.append('<div><div class="didyouknow_elem add_didyouknow_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] edit>>', addelem.find('.add_didyouknow_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddidyouknowbox').find('.add_didyouknow_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="didyouknow_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_didyouknow_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset(); // Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] didyouknow>>'
}
this.elementcont.tags.push('didyouknowbox');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['didyouknowbox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_didyouknow_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var didyouknowgeoeditor_number = 0;
var elements = this.dialogbox.find('.didyouknow_elem');
var didyouknowderiv_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_didyouknow_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_didyouknow_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph didyouknowgeoeditor'+didyouknowgeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['didyouknowgeoeditor'+didyouknowgeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
didyouknowgeoeditor_number++;
} else if (elements.eq(i).hasClass('add_didyouknow_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_didyouknow_deriv')){
this.elementdata.content += '<<qedderiv didyouknowsd'+didyouknowderiv_number+' savehere>>\n';
didyouknowderiv_number++;
} else if (elements.eq(i).hasClass('add_didyouknow_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_didyouknow_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_didyouknow_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createHistory = function(){
/******************************************************
* Tool for creating a new historybox
* TODO: combine more with createExample
******************************************************/
var tool = this;
this.tiddlerName = this.findFreeTiddler('history');
this.openDialog('addhistorybox', 'Create new history', ['add_history_head', 'tag_insert', 'add_history_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_history_head')
.append('<h2>Historybox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_history_elem')
.append('<h2>Historybox content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem').append('<div><textarea class="history_elem add_history_text"></textarea></div>');
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem');
var geoeditornum = addelem.find('.add_history_geoeditor').length;
addelem.append('<div><div class="history_elem add_history_geoeditor historygeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph historygeoeditor_'+geoeditornum+'>>', addelem.find('.add_history_geoeditor.historygeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem').append('<div class="mathdisplaystyle"><span class="history_elem add_history_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem');
var funcgnro = addelem.find('.add_history_funcgraph').length;
addelem.append('<div><div class="history_elem add_history_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_history_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem');
addelem.append('<div><div class="history_elem add_history_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_history_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem');
var tablenro = addelem.find('.add_history_table').length;
addelem.append('<div><div class="history_elem add_history_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_history_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addhistorybox').find('.add_history_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="history_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_history_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset(); // Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] history>>'
}
this.elementcont.tags.push('historybox');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['historybox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_history_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var historygeoeditor_number = 0;
var elements = this.dialogbox.find('.history_elem');
var historyderiv_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_history_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_history_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_history_deriv')){
this.elementdata.content += '<<qedderiv historysd'+historyderiv_number+' savehere>>\n';
historyderiv_number++;
} else if (elements.eq(i).hasClass('add_history_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph historygeoeditor'+historygeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['historygeoeditor'+historygeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
historygeoeditor_number++;
} else if (elements.eq(i).hasClass('add_history_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_history_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_history_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createAssignment = function(){
/******************************************************
* Tool for creating a new assignment
******************************************************/
this.tiddlerName = this.findFreeTiddler('assignment');
var result = {tiddler: '', level: 0, atype: ''};
var add_assignment_text_all={
'level': '<form><div class="assigment_level_changer"><input type="radio" id="level0" name="level" value=0 /><label for="level0">*</label> <input type="radio" id="level1" value=1 name="level" /><label for="level1">**</label> <input type="radio" id="level2" value=2 name="level" /><label for="level2">***</label></div></form>',
'tags': 'Insert tags <input class="tags_input" type="text"/>(separate tags with space)',
'title': '<div class="add_elem ebook_title">Additional title:<input type="text" class="add_ebook_title"/></div>'
}
var add_assignment_text = '<div class="add_elem assignmentText"><span class="mathquill-textbox"></span></div>';
var add_solution_text = '<div class="assignmentSolution solutionText"><span class="mathquill-textbox"></span></div>';
var add_displayform_text = '<div class="add_elem mathdisplaystyle"><span class="theory_elem add_theory_formula mathquill-editable"></span></div>';
this.openDialog('addassignment', 'Create new assignment', ['add_assignment_level', 'add_assignment_title', 'tag_insert', 'add_assignment_elem', 'add_button_bar', 'add_assignment_solution']); // Localization
this.dialogbox.siblings('.ui-dialog-buttonpane').find('button:contains("Save")').button('disable'); //Localization
var tool = this;
tool.dialogbox.find('.tag_insert').append(add_assignment_text_all.tags);
tool.dialogbox
.find('.add_assignment_level')
.append(add_assignment_text_all.level)
.find('.assigment_level_changer').buttonset();
tool.dialogbox
.find('.add_assignment_title')
.append(add_assignment_text_all.title);
tool.dialogbox
.find('.add_assignment_elem')
.append('<h2>Assignment text</h2>');
tool.dialogbox
.find('.add_assignment_solution')
.append('<h2>Assignment solution</h2>'+add_solution_text)
.find('.assignmentSolution .mathquill-textbox')
.mathquill('textbox');
tool.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Add text paragraph</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem')
.append(add_assignment_text)
.find('.mathquill-textbox:not(mathquill-editable):last')
.mathquill('textbox')
.focus();
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var geoeditornum = addelem.find('.add_assignment_geoeditor').length;
addelem.append('<div><div class="add_elem add_assignment_geoeditor assignmentgeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph assignmentgeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_assignment_geoeditor.assignmentgeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem')
.append(add_displayform_text)
.find('.mathquill-editable:last')
.mathquill('editable')
.focus();
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var funcgnro = addelem.find('.add_assignment_funcgraph').length;
addelem.append('<div><div class="add_elem add_assignment_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_assignment_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var tablenro = addelem.find('.add_assignment_table').length;
addelem.append('<div><div class="add_elem add_assignment_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_assignment_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="add_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_assignment_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
addelem.append('<div><div class="add_elem add_assignment_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_assignment_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
tool.dialogbox.siblings('.ui-dialog-buttonpane').find('button:contains("Save")').button('enable'); //Localization
//var assignmentdata;
tool.save = function(){
tool.assignmentdata = {
'ebooktitle': tool.dialogbox.find('.add_assignment_title input').val(),
'tags': tool.dialogbox.find('.tag_insert input.tags_input').val().split(" "),
'content': '',
'level': tool.dialogbox.find('input[name="level"]:checked').val(),
'atype': '0',
'graphdata' : {},
'data': {}
}
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var assignmentgeoeditor_number = 0;
var asselements = tool.dialogbox.find('.add_assignment_elem div.add_elem');
for (var i = 0; i<asselements.length; i++){
if (asselements.eq(i).hasClass('assignmentText')){
tool.assignmentdata.content += asselements.eq(i)
.find('.mathquill-editable')
.mathquill('latex')
.replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
} else if (asselements.eq(i).hasClass('mathdisplaystyle')){
tool.assignmentdata.content += '\\[' + asselements.eq(i)
.find('.mathquill-editable')
.mathquill('latex')
.replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\\]\n';
} else if (asselements.eq(i).hasClass('add_assignment_funcgraph')){
tool.assignmentdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(tool.assignmentdata.emathfuncgraph) == 'undefined'){
tool.assignmentdata.data.emathfuncgraph = {};
}
tool.assignmentdata.data.emathfuncgraph['funcg'+graphcount] = asselements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (asselements.eq(i).hasClass('add_assignment_geoeditor')){
var sizeParam = 'full';
var sizeValue = asselements.eq(i).find('.imageSize').val();
if(asselements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += asselements.eq(i).find('.imageFloat').val();
this.assignmentdata.content += '<<geograph assignmentgeoeditor'+assignmentgeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.assignmentdata.data.geoeditors) == 'undefined'){
this.assignmentdata.data.geoeditors = {};
}
this.assignmentdata.data.geoeditors['assignmentgeoeditor'+assignmentgeoeditor_number] = asselements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
assignmentgeoeditor_number++;
} else if (asselements.eq(i).hasClass('add_assignment_table')){
this.assignmentdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.assignmentdata.data.emathtable) == 'undefined'){
this.assignmentdata.data.emathtable = {};
}
this.assignmentdata.data.emathtable['table'+tablecount] = asselements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (asselements.eq(i).hasClass('add_nline_content')){
this.assignmentdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.assignmentdata.data.nline = this.nlines;
}
nlinecount++;
} else if (asselements.eq(i).hasClass('add_assignment_image')){
if (imagecount == 0){
this.assignmentdata.imagedata = [];
}
this.assignmentdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.assignmentdata.imagedata.push(JSON.parse(asselements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
if(typeof(tool.assignmentdata.level) == 'undefined'){
alert('Set assignment level');
return false;
}
tool.assignmentdata.tags.push('assignment');
tool.assignmentdata.content += '\n<data>{"assignmentType": '+tool.assignmentdata.atype+', "level": '+tool.assignmentdata.level+',"assignmentSolution": ' + JSON.stringify(tool.dialogbox.find('.assignmentSolution .mathquill-textbox').mathquill('latex')) + '}</data>';
this.requestLockType();
return false;
}
return this.tiddlerName;
}
Authortool.prototype.addAssignment = function(){
/******************************************************
* Tool for adding a new assignment
******************************************************/
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 1){
var tool = this;
tool.lockType = 'assignment';
this.assignmentSavehandler = function(){
var asslist = jQuery('#pageOne').find('.sdbookassignmentlist');
var accordiantiddlername = asslist.children('span[tiddler]').attr('tiddler');
var accordiantiddler = store.getTiddler(accordiantiddlername);
var regexp_replace= new RegExp("(<<assignmentAccordion[^>]*)>>","g");
accordiantiddler.set(accordiantiddler.title,
accordiantiddler.text.replace(regexp_replace,'$1 '+tool.tiddlerName+'>>'),
config.options.txtUserName,
new Date());
tool.sendFifo.push({"title": accordiantiddlername, "newTiddler": 1});
autoSaveChanges();
}
this.createAssignment();
} else {
alert('No assignments');
}
}
Authortool.prototype.saveAssignmentElements = function(){
/******************************************************
* Save assignmenttiddlers of new element and push to sendFifo.
******************************************************/
this.tiddlerName = this.findFreeTiddler(this.elemtype);
var tool = this;
switch(this.elemtype){
case "assignment":
if(typeof(this.assignmentdata.imagedata) != 'undefined'){
for(var i=0;i<this.assignmentdata.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.assignmentdata.content = this.assignmentdata.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.assignmentdata.imagedata[i].content, this.assignmentdata.imagedata[i].tags, this.assignmentdata.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.assignmentdata.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
this.saveTiddler(tool.tiddlerName, tool.assignmentdata.content, tool.assignmentdata.tags, tool.assignmentdata.ebooktitle);
for (datakey in this.assignmentdata.data){
DataTiddler.setData(tool.tiddlerName, datakey, this.assignmentdata.data[datakey], {});
}
//DataTiddler.setData(tool.tiddlerName, 'graphs', tool.assignmentdata.graphdata, {});
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.assignmentSavehandler();
break;
case "otherassignment":
if(typeof(this.elementcont.imagedata) != 'undefined'){
for(var i=0;i<this.elementcont.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.elementcont.content = this.elementcont.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.elementcont.imagedata[i].content, this.elementcont.imagedata[i].tags, this.elementcont.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.elementcont.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
var tempAssignmentName = "";
for(var i=0;i<tool.elementdata.length;i++){
tempAssignmentName=this.findFreeTiddler("assignment");
this.elementcont.content = this.elementcont.content.replace(tool.elementdata[i].placeHolder,tempAssignmentName);
this.elementdata[i].saveToTiddler(tempAssignmentName);
this.sendFifo.push({"title": tempAssignmentName, "newTiddler": 1});
}
tool.saveTiddler(tool.tiddlerName, tool.elementcont.content, tool.elementcont.tags, tool.elementcont.ebooktitle);
if(!jQuery.isEmptyObject(tool.elementcont.data)){
for (datakey in this.elementcont.data){
DataTiddler.setData(tool.tiddlerName, datakey, this.elementcont.data[datakey], {});
}
}
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.assignmentSavehandler();
break;
default:
alert('Something went wrong!');
}
this.callNext();
}
Authortool.prototype.addOtherassignment = function(){
/******************************************************
* Tool for adding a new 'other' typed assignment
******************************************************/
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 1){
DataTiddler.setData('QedDerivationsData','derivations',{});
var tool = this;
this.lockType = "assignment";
this.assignmentSavehandler = function(){
var asslist = jQuery('#pageOne').find('.sdbookassignmentlist');
var accordiantiddlername = asslist.children('span[tiddler]').attr('tiddler');
var accordiantiddler = store.getTiddler(accordiantiddlername);
if (accordiantiddler.text.match(/otherassignmentAccordion/g)){
var textList = accordiantiddler.text.split('\n');
var regexp_replace= new RegExp("(<<otherassignmentAccordion[^>]*)>>","g");
accordiantiddler.set(accordiantiddler.title,
textList[0].replace(regexp_replace,'$1 '+tool.tiddlerName+'>>\n')+textList[1],
config.options.txtUserName,
new Date());
}else{
accordiantiddler.set(accordiantiddler.title,
'<<otherassignmentAccordion '+tool.tiddlerName+'>>\n'+accordiantiddler.text,
config.options.txtUserName,
new Date());
}
tool.sendFifo.push({"title": accordiantiddlername, "newTiddler": 1});
autoSaveChanges();
}
this.createOtherassignment();
} else {
alert('No assignments');
}
}
Authortool.prototype.createTableElem = function(){
/******************************************************
* Tool for creating new table element (.ebooktable)
******************************************************/
testilogit.crtable = this;
var tool = this;
this.openDialog('addtableelembox', 'Create new table element', ['add_table_caption', 'add_table_content', 'add_table_edittypes', 'tag_insert']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_table_caption')
.append('<h2>Table caption:</h2><span class="tablecaption mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_table_edittypes')
.append('<a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a>')
.find('a.edittypebutton')
.click(function(){
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable();
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes();
}
})
.button();
this.dialogbox
.find('.add_table_content')
.append('<table><tbody></tbody></table>');
var tdelem = {
'text':'<td><span class="mathquill-textbox tablecell"></span></td>',
'math':'<td><span class="mathquill-editable tablecell"></span></td>'
};
this.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
this.refreshTable = function(){
var tablebody = this.dialogbox.find('.add_table_content table tbody');
tablebody.empty();
for (var i = 0; i<this.tables['table0'].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables['table0'].cols; j++){
lasttr.append(tdelem[this.tables['table0'].types[i][j]]);
lasttr.find('td .mathquill-editable, td .mathquill-textbox').last().append(this.tables['table0'].data[i][j]);
}
}
tablebody.find('.mathquill-editable').not('.mathquill-rendered-math').mathquill('editable');
tablebody.find('.mathquill-textbox').not('.mathquill-rendered-math').mathquill('textbox');
tablebody.find('.mathquill-editable').focusout(function(){
var cell = jQuery(this);
var value = cell.mathquill('latex');//.replace(/\$([^\$]*)\$/g, '\\($1\\)');
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var tcell = cell.parents('td').eq(0);
var row = ttable.children('tbody').children('tr').index(trow);
var col = trow.children('td').index(tcell);
tool.tables['table0'].data[row][col] = value;
});
tablebody.parent().attr('class','').addClass(this.tables['table0'].class);
}
this.refreshTableTypes = function(){
var tablebody = this.dialogbox.find('.add_table_content table tbody');
tablebody.empty();
for (var i = 0; i<this.tables['table0'].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables['table0'].cols; j++){
lasttr.append('<td class="tabletexttype"><span>'+this.tables['table0'].types[i][j]+'</span></td>');
}
}
tablebody.find('td.tabletexttype').click(function(){
var cell = jQuery(this);
var value = cell.text().toLowerCase();
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var row = parseInt(ttable.children('tbody').children('tr').index(trow));
var col = parseInt(trow.children('td').index(cell));
if (tool.tables['table0'].data[row][col] == ''){
tool.tables['table0']['types'][row][col] = (value == 'text' ? 'math':'text');
tool.refreshTableTypes();
} else {
alert('You can only change the type of empty cells.');
}
});
tablebody.parent().attr('class','').addClass(this.tables['table0'].class);
}
this.save = function(){
this.tables['table0'].caption = this.dialogbox.find('.add_table_caption .tablecaption').mathquill('latex').replace(/\$([^\$]*)\$/g, '\\($1\\)');
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebooktable [[tiddlernameplaceholder_data]] '+this.tables['table0'].class+'>>'
}
this.elementcont.tags.push('ebooktable');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['ebooktable','data'],
'content': '',
'data': {"table": this.tables}
};
this.finishAuthoring();
return true;
}
var tableopttool = new Authortool();
tableopttool.parent = this;
tableopttool.createTable(this.tables['table0']);
}
Authortool.prototype.createTable = function(returnobj, tnumber){
/******************************************************
* Tool for creating new table
******************************************************/
var tableClasses = ['default_table','value_table', 'column_table', 'theorytable','no_borders','casetable'];
var classHtml = '';
if (tableClasses.length > 0){
classHtml += '<select class="table_class">';
for (var i = 0; i<tableClasses.length; i++){
classHtml += '<option value="'+tableClasses[i]+'">'+tableClasses[i]+'</option>';
}
classHtml += '</select>';
}
this.openDialog('addtablebox', 'Create new table', ['add_table_options', 'table_example']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.table_example')
.append('<table><tbody><tr><td>value</td><td>value</td></tr><tr><td>value</td><td>value</td></tr></tbody></table>');
this.dialogbox
.find('.add_table_options')
.append('<h2>Options:</h2>\n<div><div class="table_cols_label">cols: <span class="table_cols_value">2</span></div><div class="table_cols"></div><div class="table_rows_label">rows: <span class="table_rows_value">2</span></div><div class="table_rows"></div><h2>Style:</h2>'+classHtml+'</div>')
.find('.table_rows').slider({
min: 1,
max: 40,
value: 2,
slide: function(event, ui){
jQuery(this).parents('.add_table_options').find('.table_rows_label .table_rows_value').empty().append(ui.value);
var tablecontent = jQuery('<tbody></tbody>');
var rowsnum = ui.value;
var colsnum = dialogbox.find('.table_cols').slider('value');
for (var i = 0; i<rowsnum; i++){
tablecontent.append('<tr></tr>');
var row = tablecontent.find('tr').last();
for (var j=0; j<colsnum; j++){
row.append('<td>value</td>');
}
}
dialogbox.find('.table_example table').empty().append(tablecontent);
}
}).end()
.find('.table_cols').slider({
min: 1,
max: 10,
value: 2,
slide: function(event, ui){
jQuery(this).parents('.add_table_options').find('.table_cols_label .table_cols_value').empty().append(ui.value);
var tablecontent = jQuery('<tbody></tbody>');
var rowsnum = dialogbox.find('.table_rows').slider('value');
var colsnum = ui.value;
for (var i = 0; i<rowsnum; i++){
tablecontent.append('<tr></tr>');
var row = tablecontent.find('tr').last();
for (var j=0; j<colsnum; j++){
row.append('<td>value</td>');
}
}
dialogbox.find('.table_example table').empty().append(tablecontent);
}
});
this.dialogbox
.find('.add_table_options select.table_class')
.change(function(){
dialogbox.find('.table_example table').attr('class','').addClass(jQuery(this).val());
});
this.save = function(){
returnobj['rows'] = this.dialogbox.find('.table_rows').slider('value');
returnobj['cols'] = this.dialogbox.find('.table_cols').slider('value');
returnobj['class'] = this.dialogbox.find('.add_table_options select.table_class').val();
returnobj['data'] = [];
returnobj['types'] = []
for (var i = 0; i<returnobj.rows; i++){
returnobj.data.push([]);
returnobj.types.push([]);
for (var j = 0; j<returnobj.cols; j++){
returnobj.data[i].push('');
returnobj.types[i].push('text');
}
}
this.parent.refreshTable(tnumber);
return true;
}
}
Authortool.prototype.createNumberline = function(returnobj, nlnumber){
/******************************************************
* Tool for creating new numberline
******************************************************/
if (typeof(nlnumber) == 'undefined'){
nlnumber = 0;
}
var tool = this;
var colorSelector = '<select class="color_selector" style="background-color:red;color:white;"><option value="red" style="background-color:red;color:white;">red</option><option value="green" style="background-color:green;color:white;">green</option><option value="blue" style="background-color:blue;color:white;">blue</option><option value="black" style="background-color:black;color:white;">black</option><option value="violet" style="background-color:violet;color:white;">violet</option></select>';
this.openDialog('addnumberline', 'Create new numberline', ['add_nline_caption', 'add_nline_options', 'add_nline_point', 'add_button_bar', 'add_nline_preview']); // Localization
var faceSelector = '<select class="face_selector"><option value="o">o</option><option value="[]">[]</option><option value="+">+</option><option value="x">x</option><option value="^">^</option><option value="v">v</option><option value="<"><</option><option value=">">></option><option value="<>"><></option></select>';
this.nline = new EmathbookNumberline();
var nline = this.nline;
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_nline_caption')
.append('<h2>Numberline caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox
.find('.add_nline_options')
.append('<h2>Options:</h2>\n<div class="nline_range_label">Range: <span class="nline_range">-10 — 10</span></div><div class="nline_range_slider"></div>')
.find('.nline_range_slider').slider({
range: true,
min: -100,
max: 100,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_nline_options').find('.nline_range_label .nline_range').empty().append(ui.values[0] +' — '+ui.values[1]);
}
});
this.dialogbox
.find('.add_nline_point')
.append('<h2>Points:</h2>\n<table class="nline_add_table"><tr>\n<th>name</th>\n<th>type</th>\n<th>value</th>\n<th>stroke color</th>\n<th>fill color</th>\n<th>face</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_point_button">Add point</button><button class="nline_preview">Preview</button></div>')
.find('.add_point_button').click(function(){
jQuery(this).parents('#authordialog_addnumberline').find('.add_nline_point table.nline_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addpointname" title="You can use names with letters and possibly ending with numbers, i.e., of form: [a-zA-Z]+[0-9]*" /></td><td><select class="addpointtype"><option value="point">point</option><option value="glider">glider</option></select></td><td><input type="text" class="addpointvalue" /></td><td class="nlstrokecolor">'+colorSelector+'</td><td class="nlfillcolor">'+colorSelector+'</td><td>'+faceSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('input.addpointname').focusout(function(){
jQuery(this).removeClass('value_error');
if (!jQuery(this).val().match(/^[a-zA-Z]+[0-9]*$/)){
jQuery(this).addClass('value_error');
}
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.nline_preview').click(function(){
var alldata = {"nline": {"nline0":{}}};
var nlinedatas = tool.getNlineData(dialogbox);
dialogbox.find('.add_nline_point table.nline_add_table tr input.addpointname').each(function(){
jQuery(this).parents('tr').eq(0).removeClass('value_error');
if (jQuery(this).val() in nlinedatas[1]){
jQuery(this).parents('tr').eq(0).addClass('value_error');
}
});
alldata.nline.nline0 = nlinedatas[0];
var tiddler;
if (store.tiddlerExists('CreateNumberlinePreview')){
tiddler = store.getTiddler('CreateNumberlinePreview');
} else {
tiddler = store.createTiddler('CreateNumberlinePreview');
}
tiddler.set(tiddler.title,'<<ebooknumberline nline0 savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
wikify('<<tiddler [[CreateNumberlinePreview]]>>', dialogbox.find('.add_nline_preview').empty()[0]);
}).end()
.buttonset();
this.getNlineData = function(elem){
var $elem = jQuery(elem);
var nlobj = new EmathbookNumberline();
jQuery('body').append('<div id="jsxgtestdiv123123" style="display:none;"></div>');
nlobj.create(jQuery('#jsxgtestdiv123123'));
var nlinedata = {
"text": $elem.find('.add_nline_caption .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'),
"startval": $elem.find('.add_nline_options .nline_range_slider').slider('values',0),
"endval": $elem.find('.add_nline_options .nline_range_slider').slider('values',1),
"points": {}
};
var points = {};
$elem.find('.add_nline_point table.nline_add_table tr.datarow').each(function(){
var pointdata = {
"ptype": jQuery(this).find('select.addpointtype').val(),
"xcoord": jQuery(this).find('input.addpointvalue').val(),
"color": jQuery(this).find('.nlstrokecolor select.color_selector').val(),
"fillcolor": jQuery(this).find('.nlfillcolor select.color_selector').val(),
"face": jQuery(this).find('select.face_selector').val().replace('<','<').replace('>','>')
}
if (pointdata.xcoord == parseFloat(pointdata.xcoord)){
pointdata.xcoord = parseFloat(pointdata.xcoord);
}
points[jQuery(this).find('.addpointname').val()] = pointdata;
});
var keepGoing = true;
while (!jQuery.isEmptyObject(points) && keepGoing){
keepGoing = false;
for (var name in points){
if (typeof(points[name].xcoord) == 'number' || !points[name].xcoord.match(/X\([a-zA-Z]+[0-9]*\)/) || (points[name].xcoord.match(/X\([a-zA-Z]+[0-9]*\)/)[0].replace(/X\(([a-zA-Z]+[0-9]*)\)/,'$1') in nlinedata.points)){
nlobj.setdata(nlinedata);
try {
nlinedata.points[name] = points[name];
nlobj.setdata(nlinedata);
nlobj.update();
} catch (e) {
delete nlinedata.points[name];
continue;
}
delete points[name];
keepGoing = true;
}
}
}
jQuery('#jsxgtestdiv123123').remove();
return [nlinedata, points];
}
this.save = function(){
var nldata = this.getNlineData(dialogbox);
if (jQuery.isEmptyObject(nldata[1])){
returnobj['nline'+nlnumber] = nldata[0];
this.parent.refreshNline(nlnumber);
return true;
} else {
dialogbox.find('.nline_preview').click();
return false;
}
}
}
Authortool.prototype.joinImage = function(returnelem){
/******************************************************
* Tool for joining preAttached image to the book
******************************************************/
this.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
var tool = this;
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input class="x_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input class="y_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" checked="checked" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var allimages = store.getTaggedTiddlers('looseImage');
var selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li').eq(0).addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imageTiddlers[0].title+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
this.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
switch(jQuery(event.target).text()){
case 'Not fixed images':
allimages = store.getTaggedTiddlers('looseImage');
selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
break;
case 'All images':
allimages = store.getTaggedTiddlers('ebookimage');
selectedImageTiddlers = [];
for (var i = 0; i<allimages.length; i++){
if (allimages[i].title.split('_')[0] == EbookPages[0].ebook.bookid){
selectedImageTiddlers.push(allimages[i]);
}
}
break;
case 'Choice tag':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
default:
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
}
initImageList(selectedImageTiddlers);
});
this.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
//returnelem.find('.imagecontainer').append('[img['+this.imageTiddler+']]');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+this.dialogbox.find('.x_size input.x_size_input').val()+"\n!size-y\n"+this.dialogbox.find('.y_size input.y_size_input').val();
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookgraph [[tiddlernameplaceholder]] image>>'
}
this.elementcont.tags.push('ebookgraph_image');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),
'content': content,
'imageTiddler':this.imageTiddler
}
returnelem.find('.imagedata').append(JSON.stringify(this.elementdata));
wikify('[img['+this.imageTiddler+']]',returnelem.find('.imagecontainer')[0]);
return true;
}
return true;
}
Authortool.prototype.createGraph = function(returnelem){
/******************************************************
* Tool for creating new graphs
******************************************************/
var colorSelector = '<select class="color_selector" style="background-color:#a00;color:white;"><option value="#a00" style="background-color:#a00;color:white;">red</option><option value="#0a0" style="background-color:#0a0;color:white;">green</option><option value="#00a" style="background-color:#00a;color:white;">blue</option><option value="#000" style="background-color:#000;color:white;">black</option><option value="#a0a" style="background-color:#a0a;color:white;">violet</option></select>';
var colorSelector = '<select class="color_selector" style="background-color:red;color:white;"><option value="red" style="background-color:red;color:white;">red</option><option value="green" style="background-color:green;color:white;">green</option><option value="blue" style="background-color:blue;color:white;">blue</option><option value="black" style="background-color:black;color:white;">black</option><option value="violet" style="background-color:violet;color:white;">violet</option></select>';
this.openDialog('addgraphbox', 'Create new graph', ['add_graph_caption', 'add_graph_options', 'add_graphfunc_elem', 'add_graphpoint_elem', 'add_graphslider_elem', 'add_button_bar']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_graph_caption')
.append('<h2>Graph caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox
.find('.add_graph_options')
.append('<h2>Options:</h2>\n<div>Axis: <input type="checkbox" class="graph_axis" checked="checked" /><div class="graph_xsize_label">x-range: <span class="graph_xrange">-10 — 10</span></div><div class="graph_xsize"></div><div class="graph_ysize_label">y-range: <span class="graph_yrange">-10 — 10</span></div><div class="graph_ysize"></div></div>')
.find('.graph_xsize').slider({
range: true,
min: -200,
max: 200,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_graph_options').find('.graph_xsize_label .graph_xrange').empty().append(ui.values[0] +' — '+ui.values[1]);
}
}).end()
.find('.graph_ysize').slider({
range: true,
min: -200,
max: 200,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_graph_options').find('.graph_ysize_label .graph_yrange').empty().append(ui.values[0] +' — '+ui.values[1]);
}
});
this.dialogbox
.find('.add_graphfunc_elem')
.append('<h2>Functions:</h2>\n<table class="graph_add_table"><tr>\n<th>function</th>\n<th>label</th>\n<th>color</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_graphpoint_elem')
.append('<h2>Points:</h2>\n<table class="graph_add_table"><tr>\n<th>x-coord</th>\n<th>y-coord</th>\n<th>label</th>\n<th>color</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_graphslider_elem')
.append('<h2>Sliders:</h2>\n<table class="graph_add_table"><tr>\n<th>variable</th>\n<th>min</th>\n<th>max</th>\n<th>default</th>\n<th>step</th>\n<th>label</th>\n</tr>\n</table>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_function_button">Add function</button><button class="add_point_button">Add point</button><button class="add_slider_button">Add slider</button><button class="remove_slider_button">Remove slider</button><button class="graph_preview">Preview</button></div>')
.find('.add_function_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphfunc_elem table.graph_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addfunction" /></td><td><span class="addlabel mathquill-editable"></span></td><td>'+colorSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.add_point_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphpoint_elem table.graph_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addpointx" /></td><td><input type="text" class="addpointy" /></td><td><span class="addlabel mathquill-editable"></span></td><td>'+colorSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.add_slider_button').click(function(){
var svars = [];
jQuery(this).parents('#authordialog_addgraphbox')
.find('.add_graphslider_elem table.graph_add_table td.slidervar')
.each(function(){
var varname = jQuery(this).text();
if (svars.indexOf(varname) == -1){
svars.push(varname);
}
});
var allvars = ['s0','s1','s2','s3','s4'];
var newvar = '';
for (var i = 0; i<allvars.length; i++){
if (svars.indexOf(allvars[i]) == -1){
newvar = allvars[i];
break;
}
}
if (newvar != ''){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphslider_elem table.graph_add_table tr:last').after('<tr class="datarow"><td class="slidervar">'+newvar+'</td><td><input type="text" class="addslidermin" /></td><td><input type="text" class="addslidermax" /></td><td><input type="text" class="addsliderdefault" /></td><td><input type="text" class="addsliderstep" /></td><td><span class="addlabel mathquill-editable"></span></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}
}).end()
.find('.remove_slider_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphslider_elem table.graph_add_table tr:last').remove();
}).end()
.find('.graph_preview').click(function(){
var preview = jQuery('<div id="grpreview"></div>');
var alldata = {"graphs":{"graph0":{}}};
alldata.graphs.graph0 = getGraphData(dialogbox);
var tiddler;
if (store.tiddlerExists('createGraphPreview')){
tiddler = store.getTiddler('createGraphPreview');
} else {
tiddler = store.createTiddler('createGraphPreview');
}
tiddler.set(tiddler.title,'<<ebookgraph graph0 functiongraph savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
preview.dialog({
buttons: {
"Close": function(){jQuery(this).dialog("destroy").remove();}
}, //Localization!!
width: 800,
height: 800,
autoOpen: true,
title: 'Graph preview',
modal: true,
close: function(){
jQuery(this).dialog("close").dialog("destroy").remove();
}
});
wikify('<<tiddler [[createGraphPreview]]>>', jQuery('#grpreview')[0]);
}).end()
.buttonset();
var getGraphData = function(elem){
var $elem = jQuery(elem);
var graphdata = {
"caption": $elem.find('.add_graph_caption .mathquill-textbox').mathquill('latex'),
"axis": ($elem.find('.add_graph_options input.graph_axis:checked').length == 1),
"area": [
$elem.find('.add_graph_options .graph_xsize').slider('values',0),
$elem.find('.add_graph_options .graph_ysize').slider('values',1),
$elem.find('.add_graph_options .graph_xsize').slider('values',1),
$elem.find('.add_graph_options .graph_ysize').slider('values',0)
],
"sizex": "500",
"sizey": "auto",
"sliders": [],
"data": []
}
$elem.find('.add_graphfunc_elem table.graph_add_table tr.datarow').each(function(){
var funcdata = {
"type": "function",
"formula_js": jQuery(this).find('input.addfunction').val(),
"color": jQuery(this).find('select.color_selector').val(),
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex'),
"formula_latex": ""
}
graphdata.data.push(funcdata);
});
$elem.find('.add_graphpoint_elem table.graph_add_table tr.datarow').each(function(){
var pointdata = {
"type": "point",
"xcoord": parseFloat(jQuery(this).find('input.addpointx').val()) || 0,
"ycoord": parseFloat(jQuery(this).find('input.addpointy').val()) || 0,
"color": jQuery(this).find('select.color_selector').val(),
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex')
}
pointdata.label += '= (' + pointdata.xcoord + ',' + pointdata.ycoord + ')';
graphdata.data.push(pointdata);
});
$elem.find('.add_graphslider_elem table.graph_add_table tr.datarow').each(function(){
var sliderdata = {
"min": parseFloat(jQuery(this).find('input.addslidermin').val()) || 0,
"max": parseFloat(jQuery(this).find('input.addslidermax').val()) || 0,
"value": parseFloat(jQuery(this).find('input.addsliderdefault').val()) || 0,
"step": parseFloat(jQuery(this).find('input.addsliderstep').val()) || 0,
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex')
}
graphdata.sliders.push(sliderdata);
});
return graphdata;
}
this.save = function(){
var grdata = getGraphData(this.dialogbox);
if (typeof(returnelem) != 'undefined' && returnelem != null){
jQuery(returnelem).find('.graphdata').append(JSON.stringify(grdata));
var alldata = {"graphs":{"graph0":{}}};
alldata.graphs.graph0 = getGraphData(dialogbox);
var tiddler = store.getTiddler('createGraphPreview');
tiddler.set(tiddler.title,'<<ebookgraph graph0 functiongraph savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
// store.dirty = true;
// if (config.options.chkAutoSave){
// setTimeout("saveChanges();", 500);
// }
wikify('<<tiddler [[createGraphPreview]]>>',jQuery(returnelem).find('.graphcontainer')[0]);
}
return true;
}
}
Authortool.prototype.createImage = function(parenttool){
/******************************************************
* Tool for creating (adding) images
******************************************************/
this.openDialog('addimagebox', 'Add new image', ['add_image_options', 'add_image_elem', 'add_button_bar']); // Localization
wikify('<<attachimage tmpimage_0>>', this.dialogbox.find('.add_image_elem')[0]);
var imagemimes = ['.png','.jpg','.jpeg','.gif'];
if (typeof(this.elemtype) == 'undefined'){
this.elemtype = 'ebookimage';
}
this.save = function(){
/*
* Kupongin tarkistus
*
*/
this.imagedata = {};
this.tiddlerName = this.findFreeTiddler(this.elemtype);
var form = this.dialogbox.find('form')[0];
jQuery(form).find('[name="tiddlertitle"]').val(this.tiddlername);
this.imagedata.src=form.source.value;
this.imagedata.when=(new Date()).formatString(config.macros.timeline.dateFormat);
this.imagedata.imagename = form.imagename.value;
this.imagedata.title=form.tiddlertitle.value;
this.imagedata.localpath = './data/images/';
this.imagedata.local = this.imagedata.localpath+this.imagedata.title;
this.imagedata.url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
this.imagedata.notes = form.notes.value;
this.imagedata.tags = "attachment excludeMissing ebookimage "+form.tags.value;
this.imagedata.useData=form.useData.checked;
this.imagedata.useLocal=form.useLocal.checked;
this.imagedata.useURL=form.useURL.checked;
this.imagedata.mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
this.imagedata.author = form.authordata.value;
this.imagedata.source = form.sourcedata.value;
this.imagedata.license = form.licensedata.value;
if (this.imagedata.useData) {
if (this.imagedata.src.length) {
if (!this.imagedata.theLocation){
this.imagedata.theLocation = this.imagedata.src;
} else {
alert('No file defined!'); // Localization
return false;
}
}
}
if (this.imagedata.useURL) {
if (this.imagedata.url.length) {
if (!this.imagedata.theLocation){
this.imagedata.theLocation = this.imagedata.url;
} else {
alert('No url defined!'); // Localization
return false;
}
}
}
if (!(this.imagedata.useData || this.imagedata.useLocal || this.imagedata.useURL) || !(this.imagedata.theLocation)){
alert('No file defined!'); // Localization
return false;
}
if (!this.imagedata.usedata && this.imagedata.mimetype.length > 0 && this.imagedata.theLocation.lastIndexOf('.') != -1){
var extension = this.imagedata.theLocation.substr(this.imagedata.theLocation.lastIndexOf('.')).toLowerCase();
var extlist = form.MIMEType;
for (var i=0; i<extlist.options.length; i++){
if (extlist.options[i].value.indexOf(extension) != -1){
this.imagedata.mimetype = extlist.options[i].text;
extlist.selectedIndex=i;
break;
}
}
}
if (this.imagedata.author.length == 0 || this.imagedata.license.length == 0){
alert('You need to state the author and the license of this image.'); // Localization
return false;
}
if (this.imagedata.source.length == 0 && !confirm('Are you sure, you don\'t want to give the source of the image?')){
// Localization
alert('Attaching of image cancelled.'); // Localization
return false;
}
this.lockType = 'ebookimage';
this.requestLockType();
return false;
}
}
Authortool.prototype.createAttachmentTiddler = function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, imagename, author, source, license, noshow) {
var tool = this;
if (useData) { // encode the data
var imageError = false;
if (!mimetype.length) {
alert('Unknown filetype!'); // Localization
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
imageError = true;
}
var callback = function(data){
if (!data){
alert('Something went wrong!\nSorry!'); // Localization
imageError = true;
}
if (data.length > 100000){
alert('Too large file!\nContact Petri.'); // Localization
imageError = true;
}
if (imageError){
tool.clearCallFifo();
tool.removeLockType();
return false;
}
var encoded = config.macros.attachimage.encodeBase64(data);
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=config.macros.attachimage.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ,
imagename, author, source, license]);
tool.saveTiddler(title, theText, (tags+" looseImage").readBracketedList());
tool.sendFifo.push({"title": title, "newTiddler": 1});
tool.callNext();
}
config.macros.attachimage.readFile(src, callback);
} else {
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=config.macros.attachimage.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ,
imagename, author, source, license]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags+" looseImage");
this.sendFifo.push({"title": title, "newTiddler": 1});
this.callNext();
}
return true;
}
Authortool.prototype.createPrerequisites = function(){
/******************************************************
* Tool for creating a new prerequisitesbox
* TODO: combine more with createExample
******************************************************/
var requisite = '<li><span class="mathquill-textbox"></span></li>';
this.tiddlerName = this.findFreeTiddler('prerequisites');
this.openDialog('addprerequisites', 'Create new prerequisites list', ['add_prerequisites_head', 'tag_insert','prerequisites_list', 'add_prerequisites_elem']); // Localization
this.dialogbox
.find('.add_prerequisites_head')
.append('<h2>Prerequisitesbox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.prerequisites_list')
.append('<h2>Prerequisites:</h2><ul>'+requisite+'</ul>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox
.find('.add_prerequisites_elem')
.append('<button class="add_prerequisites_button">Add prerequisite</button>')
.find('.add_prerequisites_button').click(function(){
jQuery(this).parents('#authordialog_addprerequisites').find('.prerequisites_list ul').append(requisite)
.find('.mathquill-textbox:last').mathquill('textbox');
}).button();
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] prerequisites>>'
}
this.elementcont.tags.push('prerequisites');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['prerequisites','data'],
'content': '',
'data': {}
}
var disHead = this.dialogbox.find('.add_prerequisites_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '!' + (disHead=='' ? 'Esitiedot': disHead ) + '\n';
var elements = this.dialogbox.find('.prerequisites_list ul>li');
for (var i = 0;i<elements.length;i++){
var list_question = elements.eq(i).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '*'+list_question+'\n';
};
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createDiscussion = function(){
/******************************************************
* Tool for creating a new discussionbox
* TODO: combine more with createExample
******************************************************/
var tool = this;
var question = '<li class="question"><span class="mathquill-textbox"></span><ul></ul><button class="add_subquestion">Sub</button></li>';
var subquestion = '<li class="subquestion"><span class="mathquill-textbox"></span></li>';
this.tiddlerName = this.findFreeTiddler('discussion');
this.openDialog('adddiscussion', 'Create new discussion', ['add_discussion_head', 'tag_insert', 'add_prediscussion_elem', 'add_prebutton_bar','discussion_list', 'add_discussion_elem', 'add_postdiscussion_elem', 'add_postbutton_bar']); // Localization
this.dialogbox
.find('.add_discussion_head')
.append('<h2>Discussionbox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_prediscussion_elem')
.append('<h2>Before questions:</h2>');
this.dialogbox
.find('.discussion_list')
.append('<h2>Discussion questions:</h2><ol>'+question+'</ol>')
.find('.mathquill-textbox').mathquill('textbox')
.end()
.find('.add_subquestion')
.button().click(function(){jQuery(this).parent().find('ul').append(subquestion).find('.mathquill-textbox').mathquill('textbox');});
this.dialogbox
.find('.add_postdiscussion_elem')
.append('<h2>After questions:</h2>');
this.dialogbox
.find('.add_prebutton_bar')
.append('<div class="add_prebuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem').append('<div><textarea class="discussion_elem add_discussion_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem').append('<div class="mathdisplaystyle"><span class="discussion_elem add_discussion_formula mathquill-editable"></span></div>')
.find('.mathquill-editable').last().mathquill('editable')
.end()
.find('.add_subquestion').button();;
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem');
var geoeditornum = addelem.find('.add_discussion_geoeditor').length;
addelem.append('<div><div class="discussion_elem add_discussion_geoeditor discussiongeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph discussiongeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_discussion_geoeditor.discussiongeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem');
var funcgnro = addelem.find('.add_prediscussion_funcgraph').length;
addelem.append('<div><div class="discussion_elem add_prediscussion_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_prediscussion_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem');
addelem.append('<div><div class="discussion_elem add_discussion_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_discussion_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
this.dialogbox
.find('.add_discussion_elem')
.append('<button class="add_discussion_button">Add discussion question</button>')
.find('.add_discussion_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.discussion_list ol').append(question)
.find('.mathquill-textbox:last').mathquill('textbox')
.end()
.find('.add_subquestion:last')
.button().click(function(){jQuery(this).parent().find('ul').append(subquestion).find('.mathquill-textbox:last').mathquill('textbox');});
}).button();
this.dialogbox
.find('.add_postbutton_bar')
.append('<div class="add_postbuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_image_button">Image</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem').append('<div><textarea class="discussion_elem add_discussion_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem').append('<div class="mathdisplaystyle"><span class="discussion_elem add_discussion_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem');
var funcgnro = addelem.find('.add_postdiscussion_funcgraph').length;
addelem.append('<div><div class="discussion_elem add_postdiscussion_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_postdiscussion_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem');
addelem.append('<div><div class="discussion_elem add_discussion_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_discussion_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] discussion>>'
}
this.elementcont.tags.push('discussion');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['discussion','data'],
'content': '',
'data': {}
}
var disHead = this.dialogbox.find('.add_discussion_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '!' + (disHead=='' ? 'Pohdintaa': disHead ) + '\n';
var graphcount = 0;
var imagecount = 0;
var discussionderiv_number = 0;
var discussiongeoeditor_number = 0;
var elements = this.dialogbox.find('.add_prediscussion_elem .discussion_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_discussion_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_discussion_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_discussion_deriv')){
this.elementdata.content += '<<qedderiv discussionsd'+discussionderiv_number+' savehere>>\n';
discussionderiv_number++;
} else if (elements.eq(i).hasClass('add_discussion_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph discussiongeoeditor'+discussiongeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['discussiongeoeditor'+discussiongeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
discussiongeoeditor_number++;
} else if (elements.eq(i).hasClass('add_prediscussion_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_discussion_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
elements = this.dialogbox.find('.discussion_list ol>li');
for (var i = 0;i<elements.length;i++){
var list_question = elements.eq(i).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
var subquestion_list =elements.eq(i).children('ul').find('li.subquestion');
this.elementdata.content += '#'+list_question+'\n';
for (var j=0;j<subquestion_list.length;j++){
var list_subquestion = subquestion_list.eq(j).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
if (list_subquestion != ''){
this.elementdata.content += '##'+list_subquestion+'\n';
}
}
};
elements = this.dialogbox.find('.add_postdiscussion_elem .discussion_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_discussion_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_discussion_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_discussion_deriv')){
this.elementdata.content += '<<qedderiv discussionsd'+discussionderiv_number+' savehere>>\n';
discussionderiv_number++;
} else if (elements.eq(i).hasClass('add_postdiscussion_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_discussion_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createOtherassignment = function(){
/******************************************************
* Tool for creating a new otherassignmentbox
* TODO:
******************************************************/
testilogit.tool = this;
var tool = this;
var question = '<li class="question"><span class="mathquill-textbox"></span><ul></ul><button class="add_subquestion">Sub</button></li>';
var subquestion = '<li class="subquestion"><span class="mathquill-textbox"></span></li>';
var derivations = 0;
this.tiddlerName = this.findFreeTiddler('otherAssignment');
this.openDialog('addotherassignment', 'Create new assignment', ['add_otherassignment_head', 'tag_insert', 'add_preotherassignment_elem', 'add_prebutton_bar','otherassignment_list', 'add_otherassignment_elem', 'add_postotherassignment_elem', 'add_postbutton_bar']); // Localization
this.dialogbox
.find('.add_otherassignment_head')
.append('<h2>Additional title:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_preotherassignment_elem')
.append('<h2>Before questions:</h2>');
this.dialogbox
.find('.otherassignment_list')
.append('<h2>otherassignment questions:</h2><ol></ol>');
this.dialogbox
.find('.add_postotherassignment_elem')
.append('<h2>After questions:</h2>');
this.dialogbox
.find('.add_prebutton_bar')
.append('<div class="add_prebuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem').append('<div><textarea class="otherassignment_elem add_otherassignment_text"></textarea></div>');
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var geoeditornum = addelem.find('.add_otherassignment_geoeditor').length;
addelem.append('<div><div class="otherassignment_elem add_otherassignment_geoeditor otherassignmentgeoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph otherassignmentgeoeditor_'+geoeditornum+' full author>>', addelem.find('.add_otherassignment_geoeditor.otherassignmentgeoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem').append('<div class="mathdisplaystyle"><span class="otherassignment_elem add_otherassignment_formula mathquill-editable"></span></div>')
.find('.mathquill-editable').last().mathquill('editable')
.end()
.find('.add_subquestion').button();;
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var funcgnro = addelem.find('.add_preotherassignment_funcgraph').length;
addelem.append('<div><div class="otherassignment_elem add_preotherassignment_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_preotherassignment_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
addelem.append('<div><div class="otherassignment_elem add_otherassignment_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_otherassignment_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){
var addelem = jQuery('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var tablenro = jQuery('#authordialog_addotherassignment').find('.add_table').length;
addelem.append('<div><div class="history_elem add_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="otherassignment_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();
this.dialogbox
.find('.add_otherassignment_elem')
.append('Add Question: <select class="assignmentselection">\n <option value="0" selected="selected">Select assignment type</option>\n <option value="1">Plain Text</option>\n <option value="2">Multichoise</option>\n <option value="3">Shortanswer</option>\n <option value="5">SDshuffle</option>\n <option value="6">FillSD</option>\n <option value="7">FillTable</option>\n'+(jQuery('body').hasClass('adminmode')?' <option value="8">EmathQuiz</option>\n':'')+'</select> ')
.find('.assignmentselection').change(function(){
switch(jQuery(this).val())
{
case "1":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="1">Question text:<span class="questionPlain mathquill-editable"></span><ol class="subotherassignment_list"></ol><hr><span class="addSubQ">Add Subquestion: <select class="subassignmentselection">\n <option value="0" selected="selected">Select assignment type</option>\n <option value="2">Multichoise</option>\n <option value="3">Shortanswer</option>\n <option value="5">SDshuffle</option>\n <option value="6">FillSD</option>\n <option value="7">FillTable</option>\n</select></span></li>')
.find('.mathquill-editable:last').mathquill('textbox').focus()
.end()
.find('.subassignmentselection').change(function(){
var addplace = jQuery(this).parent().parent().find('ol.subotherassignment_list')
switch(jQuery(this).val())
{
case "2":
addplace.append('<li class="subquestion" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable"></span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable"></span></li><li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li></ul><hr><button class="addMultiwrong">Add incorrect</button></li>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end()
.find('.addMultiwrong:last').button().click(function(){
jQuery(this).parent().find('ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li>').find('.mathquill-editable:last').mathquill('textbox');
});
break;
case "3":
addplace.append('<li class="subquestion" quetionType="3">Shortanswer question:<span class="questionShortA mathquill-editable"></span></li>')
.find('span.questionShortA:last').mathquill('textbox').focus();
break;
case "5":
var questionPlace = addplace.append('<li class="subquestion" quetionType="5">Structured derivation to shuffle:<span class="questionSDshuffle" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"]')[0]);
derivations++;
break;
case "6":
var questionPlace = addplace.append('<li class="subquestion" quetionType="6">Partly filled structured derivation:<span class="questionSDfill" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"]')[0]);
derivations++;
break;
case "7":
var tablenum = addplace.parents('.dialogelement').parent().find('.add_table_content').length;
var questionPlace = addplace.append('<li class="subquestion" quetionType="7">Partly filled table:<span class="questionTablefill" assignmenttable="'+tablenum+'"></span></li>');
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addplace.find('.questionTablefill[assignmenttable="'+tablenum+'"]').append('<div class="table_container"><div class="add_table_content assignmenttable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addplace.find('.table_container:last a.edittypebutton').button().click(function(){
var tparent = jQuery(this).parents('.table_container').find('.add_table_content').eq(0);
var tablenumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tablenumber = parseInt(tablenumber);
// var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addplace.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addplace = addplace.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
break;
default:
alert("Try other");
}
jQuery(this).find('[selected="selected"]').removeAttr('selected').end().find('option').eq(0).attr('selected','selected');
});
break;
case "2":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable"></span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable"></span></li><li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li></ul><hr><button class="addMultiwrong">Add incorrect</button></li>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end()
.find('.addMultiwrong:last').button().click(function(){
jQuery(this).parent().find('ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li>').find('.mathquill-editable:last').mathquill('textbox');
});
break;
case "3":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="3">Shortanswer question:<span class="questionShortA mathquill-editable"></span></li>')
.find('span.questionShortA:last').mathquill('editable').focus();
break;
case "5":
var questionPlace = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="5">Structured derivation to shuffle:<span class="questionSDshuffle" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"]')[0]);
questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"] .command_qededit').click();
derivations++;
break;
case "6":
var questionPlace = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="6">Partly filled structured derivation:<span class="questionSDfill" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"]')[0]);
questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"] .command_qededit').click();
derivations++;
break;
case "7":
var addelem = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol');
var tablenum = addelem.parents('.dialogelement').parent().find('.add_table_content').length;
var questionPlace = addelem.append('<li class="question" quetionType="7">Partly filled table:<span class="questionTablefill" assignmenttable="'+tablenum+'"></span></li>');
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.find('.questionTablefill[assignmenttable="'+tablenum+'"]').append('<div class="table_container"><div class="add_table_content assignmenttable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tparent = jQuery(this).parents('.table_container').find('.add_table_content').eq(0);
var tablenumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tablenumber = parseInt(tablenumber);
// var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
break;
case "8":
var questionPlace = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="8">openQuiz:<input type="text" class="openQuiz"><br/>callFunction:<input type="text" class="callFunction"></li>')
.find('openQuiz:last').focus();
jQuery(this).parents('.add_otherassignment_elem').remove();
break;
default:
}
jQuery(this).find('option[value="8"]').remove();
jQuery(this).find('[selected="selected"]').removeAttr('selected').end().find('option').eq(0).attr('selected','selected');
});
this.dialogbox
.find('.add_postbutton_bar')
.append('<div class="add_postbuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem').append('<div><textarea class="otherassignment_elem add_otherassignment_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem').append('<div class="mathdisplaystyle"><span class="otherassignment_elem add_otherassignment_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem')
var funcgnro = addelem.find('.add_postotherassignment_funcgraph').length;
addelem.append('<div><div class="otherassignment_elem add_postotherassignment_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_postotherassignment_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.buttonset();
this.save = function(){
var disHead = this.dialogbox.find('.add_otherassignment_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
var placeholderNro=0;
this.elementcont = {
'ebooktitle': (disHead=='' ? '': disHead ),
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '',
'data': {}
}
this.elementcont.tags.push('otherassignment');
this.elementcont.tags.push('container');
this.elementdata = [];
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var otherassignmentderiv_number = 0;
var otherassignmentgeoeditor_number = 0;
var elements = this.dialogbox.find('.add_preotherassignment_elem .otherassignment_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_otherassignment_text')){
this.elementcont.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_otherassignment_formula')){
this.elementcont.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_otherassignment_deriv')){
this.elementcont.content += '<<qedderiv otherassignmentsd'+otherassignmentderiv_number+' savehere>>\n';
otherassignmentderiv_number++;
} else if (elements.eq(i).hasClass('add_otherassignment_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementcont.content += '<<geograph otherassignmentgeoeditor'+otherassignmentgeoeditor_number+' '+sizeParam+'>>\n';
if (typeof(this.elementcont.data.geoeditors) == 'undefined'){
this.elementcont.data.geoeditors = {};
}
this.elementcont.data.geoeditors['otherassignmentgeoeditor'+otherassignmentgeoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
otherassignmentgeoeditor_number++;
} else if (elements.eq(i).hasClass('add_preotherassignment_funcgraph')){
this.elementcont.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementcont.data.emathfuncgraph) == 'undefined'){
this.elementcont.data.emathfuncgraph = {};
}
this.elementcont.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_table')){
this.elementcont.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementcont.data.emathtable) == 'undefined'){
this.elementcont.data.emathtable = {};
}
this.elementcont.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementcont.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementcont.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_otherassignment_image')){
if (imagecount == 0){
this.elementcont.imagedata = [];
}
this.elementcont.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementcont.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
elements = this.dialogbox.find('.otherassignment_list ol>li.question');
for (var i = 0;i<elements.length;i++){
var otherQuestion = new EmathbookAssignnment("otherass_"+placeholderNro,elements.eq(i).attr('quetionType'));
this.elementcont.content += '# <<showAssignment otherass_'+placeholderNro+'>>\n';
placeholderNro++;
switch(elements.eq(i).attr('quetionType')){
case "1":
otherQuestion.setText(elements.eq(i).children('span.questionPlain').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var subquestion_list =elements.eq(i).children('ol').find('li.subquestion');
for (var j=0;j<subquestion_list.length;j++){
var othersubQuestion = new EmathbookAssignnment("otherass_"+placeholderNro,subquestion_list.eq(j).attr('quetionType'));
switch(subquestion_list.eq(j).attr('quetionType')){
case "2":
othersubQuestion.setText(subquestion_list.eq(j).children('span.questionMulti').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
othersubQuestion.setData("correct",subquestion_list.eq(j).find('ul li.correct span.correctchoice').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var $multiWrongs = subquestion_list.eq(j).find('ul li.incorrect span.incorrectchoise');
var multiWronglist = [];
for (var k=0;k<$multiWrongs.length;k++){
multiWronglist.push($multiWrongs.eq(k).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
}
othersubQuestion.setData("wrong", multiWronglist);
break;
case "3":
var SAquestion = subquestion_list.eq(j).children('.questionShortA').mathquill('latex');
var solutionsSpans= subquestion_list.eq(j).find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var SAsolution = solutionsSpans.eq(k).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
othersubQuestion.setText(SAquestion);
if (hasSolutions){othersubQuestion.setData("correct", SAsolutions);}
break;
case "5":
othersubQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{})
othersubQuestion.setData("derivations", {"assignmentsd0": shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDshuffle').attr('assignmentDeriv')]});
break;
case "6":
othersubQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
var strShuffleDerivation = shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDfill').attr('assignmentDeriv')] ? JSON.stringify(shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDfill').attr('assignmentDeriv')]) : JSON.stringify({"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"","virgin":false}],"relation":[],"motivation":[],"check":""});
var fillMotivations = elements.eq(i).find('table.sdtable td.motivation span.solution');
var fillTerms = elements.eq(i).find('table.sdtable td.term span.solution');
var fillRelations = elements.eq(i).find('table.sdtable td.relation span.solution');
var hasSolutions = true;
var solutionsSpans = jQuery.merge(fillMotivations,fillTerms);
solutionsSpans = jQuery.merge(solutionsSpans,fillRelations);
var FillSDsolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var FillSDsolution = solutionsSpans.eq(k).mathquill('latex');
FillSDsolution = (FillSDsolution.charAt(FillSDsolution.length-1)==" "? FillSDsolution.substring(0,FillSDsolution.length-1): FillSDsolution);
FillSDsolution = FillSDsolution.replace(/\ ([\+\-\}])/g,'$1');
FillSDsolutions.push(FillSDsolution);
if (FillSDsolution==""){ hasSolutions = false;}
strShuffleDerivation = strShuffleDerivation.replace('\\\\solution{'+FillSDsolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
if (hasSolutions){othersubQuestion.setData("correct", FillSDsolutions);}
othersubQuestion.setData("derivations", {"assignmentsd0": JSON.parse(strShuffleDerivation)});
break;
case "7":
var tablenro = subquestion_list.eq(j).children('.questionTablefill').attr('assignmenttable');
var FillTableData = JSON.stringify(tool.tables['table'+tablenro].data);
var solutionsSpans= subquestion_list.eq(j).find('.solution');
var hasSolutions = true;
var FillTablesolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var FillTablesolution = solutionsSpans.eq(k).mathquill('latex');
FillTablesolution = (FillTablesolution.charAt(FillTablesolution.length-1)==" "? FillTablesolution.substring(0,FillTablesolution.length-1): FillTablesolution);
FillTablesolution=FillTablesolution.replace(/\ ([\+\-\}])/g,'$1');
FillTablesolutions.push(FillTablesolution);
if (FillTablesolution==""){ hasSolutions = false;}
FillTableData = FillTableData.replace('\\\\solution{'+FillTablesolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
tool.tables['table'+tablenro].data = JSON.parse(FillTableData);
if (hasSolutions){othersubQuestion.setData("correct", FillTablesolutions);}
othersubQuestion.setText('<<ebooktable assignmentTable0 '+tool.tables['table'+tablenro].class+' savehere>>');
othersubQuestion.setData("table", {"assignmentTable0":tool.tables['table'+tablenro]});
break;
default:
}
this.elementcont.content += '## <<showAssignment otherass_'+placeholderNro+'>>\n';
placeholderNro++;
this.elementdata.push(othersubQuestion);
}
break;
case "2":
otherQuestion.setText(elements.eq(i).children('span.questionMulti').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
otherQuestion.setData("correct",elements.eq(i).find('ul li.correct span.correctchoice').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var $multiWrongs = elements.eq(i).find('ul li.incorrect span.incorrectchoise');
var multiWronglist = [];
for (var j=0;j<$multiWrongs.length;j++){
multiWronglist.push($multiWrongs.eq(j).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
}
otherQuestion.setData("wrong", multiWronglist);
break;
case "3":
var SAquestion = elements.eq(i).children('.questionShortA').mathquill('latex');
var solutionsSpans= elements.eq(i).find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var SAsolution = solutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
otherQuestion.setText('\\('+SAquestion+'\\)');
if (hasSolutions){otherQuestion.setData("correct", SAsolutions);}
break;
case "5":
otherQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
otherQuestion.setData("derivations", {"assignmentsd0": shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDshuffle').attr('assignmentDeriv')]});
break;
case "6":
otherQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
var strShuffleDerivation = shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDfill').attr('assignmentDeriv')] ? JSON.stringify(shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDfill').attr('assignmentDeriv')]) : JSON.stringify({"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"","virgin":false}],"relation":[],"motivation":[],"check":""});
var fillMotivations = elements.eq(i).find('table.sdtable td.motivation span.solution');
var fillTerms = elements.eq(i).find('table.sdtable td.term span.solution');
var fillRelations = elements.eq(i).find('table.sdtable td.relation span.solution');
var hasSolutions = true;
var solutionsSpans = jQuery.merge(fillMotivations,fillTerms);
solutionsSpans = jQuery.merge(solutionsSpans,fillRelations);
var FillSDsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var FillSDsolution = solutionsSpans.eq(j).mathquill('latex');
FillSDsolution = (FillSDsolution.charAt(FillSDsolution.length-1)==" "? FillSDsolution.substring(0,FillSDsolution.length-1): FillSDsolution);
FillSDsolution = FillSDsolution.replace(/\ ([\+\-\}])/g,'$1');
FillSDsolutions.push(FillSDsolution);
if (FillSDsolution==""){ hasSolutions = false;}
strShuffleDerivation = strShuffleDerivation.replace('\\\\solution{'+FillSDsolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
if (hasSolutions){otherQuestion.setData("correct", FillSDsolutions);}
otherQuestion.setData("derivations", {"assignmentsd0": JSON.parse(strShuffleDerivation)});
break;
case "7":
var tablenro = elements.eq(i).children('.questionTablefill').attr('assignmenttable');
var FillTableData = JSON.stringify(tool.tables['table'+tablenro].data);
var solutionsSpans= elements.eq(i).find('.solution');
var hasSolutions = true;
var FillTablesolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var FillTablesolution = solutionsSpans.eq(j).mathquill('latex');
FillTablesolution = (FillTablesolution.charAt(FillTablesolution.length-1)==" "? FillTablesolution.substring(0,FillTablesolution.length-1): FillTablesolution);
FillTablesolution=FillTablesolution.replace(/\ ([\+\-\}])/g,'$1');
FillTablesolutions.push(FillTablesolution);
if (FillTablesolution==""){ hasSolutions = false;}
FillTableData = FillTableData.replace('\\\\solution{'+FillTablesolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
tool.tables['table'+tablenro].data = JSON.parse(FillTableData);
if (hasSolutions){otherQuestion.setData("correct", FillTablesolutions);}
otherQuestion.setText('<<ebooktable assignmentTable0 '+tool.tables['table'+tablenro].class+' savehere>>');
otherQuestion.setData("table", {"assignmentTable0":tool.tables['table'+tablenro]});
break;
case "8":
this.elementcont.content = this.elementcont.content.replace('# <<showAssignment','<<showAssignment');
otherQuestion.setText(' ');
otherQuestion.setData("openQuiz", elements.eq(i).find('.openQuiz').val());
otherQuestion.setData("callFunction", elements.eq(i).find('.callFunction').val().split(' '));
break;
default:
}
this.elementdata.push(otherQuestion);
};
elements = this.dialogbox.find('.add_postotherassignment_elem .otherassignment_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_otherassignment_text')){
this.elementcont.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_otherassignment_formula')){
this.elementcont.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_otherassignment_deriv')){
this.elementcont.content += '<<qedderiv otherassignmentsd'+otherassignmentderiv_number+' savehere>>\n';
otherassignmentderiv_number++;
} else if (elements.eq(i).hasClass('add_postotherassignment_funcgraph')){
this.elementcont.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementcont.data.graphs) == 'undefined'){
this.elementcont.data.graphs = {};
}
this.elementcont.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
this.elementcont.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementcont.data.emathfuncgraph) == 'undefined'){
this.elementcont.data.emathfuncgraph = {};
}
this.elementcont.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
}
}
this.requestLockType();
return false;
}
return this.tiddlerName;
}
Authortool.prototype.saveNewElement = function(){
/******************************************************
* Save tiddlers of new element and push to sendFifo.
******************************************************/
switch(this.elemtype){
case 'joinimage':
this.imageTiddlerName = this.findFreeTiddler('image');
this.tiddlerName = this.findFreeTiddler('graphelement');
this.elementcont.content = this.elementcont.content.replace('tiddlernameplaceholder', this.imageTiddlerName);
this.saveTiddler(this.tiddlerName, this.elementcont.content, this.elementcont.tags, this.elementcont.ebooktitle);
this.saveTiddler(this.imageTiddlerName, this.elementdata.content, this.elementdata.tags, this.elementdata.ebooktitle);
store.getTiddler(this.imageTiddler).tags.remove('looseImage');
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.sendFifo.push({"title": this.imageTiddlerName, "newTiddler": 1});
this.addInTiddler();
break;
case 'hint':
case 'extra':
if(typeof(this.elementdata.imagedata) != 'undefined'){
for(var i=0;i<this.elementdata.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.elementdata.content = this.elementdata.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.elementdata.imagedata[i].content, this.elementdata.imagedata[i].tags, this.elementdata.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.elementdata.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
this.tiddlerName = this.addelemdata.refelement+'_'+this.elemtype;
this.saveTiddler(this.tiddlerName, this.elementdata.content, this.elementdata.tags, this.elementdata.ebooktitle,this.addelemdata.refelement,this.elementdata.fields);
for (datakey in this.elementdata.data){
DataTiddler.setData(this.tiddlerName, datakey, this.elementdata.data[datakey], {});
}
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
break;
default:
if(typeof(this.elementdata.imagedata) != 'undefined'){
for(var i=0;i<this.elementdata.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.elementdata.content = this.elementdata.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.elementdata.imagedata[i].content, this.elementdata.imagedata[i].tags, this.elementdata.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.elementdata.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
this.tiddlerName = this.findFreeTiddler(this.elemtype);
this.elementcont.content = this.elementcont.content.replace('tiddlernameplaceholder', this.tiddlerName);
this.saveTiddler(this.tiddlerName, this.elementcont.content, this.elementcont.tags, this.elementcont.ebooktitle);
this.saveTiddler(this.tiddlerName+'_data', this.elementdata.content, this.elementdata.tags, this.elementdata.ebooktitle);
for (datakey in this.elementdata.data){
DataTiddler.setData(this.tiddlerName+'_data', datakey, this.elementdata.data[datakey], {});
}
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.sendFifo.push({"title": this.tiddlerName+'_data', "newTiddler": 1});
this.addInTiddler();
break;
}
this.callNext();
}
Authortool.prototype.createsubelement = function(){
/******************************************************
* Tool for adding subelement to tiddler *
* -hint *
* -extra *
******************************************************/
var tool = this;
this.addelemdata = {
'pageview': jQuery('#pageOne > [tiddler]').attr('tiddler') // chapter/section/subsection, where element is added
}
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (EbookPages[0].currentlang !== EbookPages[0].ebook.defaultlang){
tool.removeLock();
tool.removeLockType();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
jQuery('#pageOneNavi').show();
alert('Add can be done only in language '+EbookPages[0].ebook.defaultlang);
return true;
}
if (assignmentlist.length == 0){
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
var tempElems = jQuery();
for(var i=0;i<pageElements.length;i++){
if(!store.tiddlerExists(pageElements.eq(i).attr('tiddler')+'_'+this.elemtype)){
tempElems = tempElems.add(pageElements.eq(i));
}
}
pageElements = tempElems;
if (pageElements.length == 0){
tool.removeLock();
tool.removeLockType();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
jQuery('#pageOneNavi').show();
alert('No element to add new '+this.elemtype);
return true;
}
pageElements.append('<div class="addsubelement""><a href="javascript:;" title="Add '+this.elemtype+'">Add '+this.elemtype+'</a></div>')
.find('.addsubelement a').click(function(){
tool.addelemdata.refelement = jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
tool.addsubelement();
jQuery('.addsubelement').remove();
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('addsubs');",30);
} else {
alert('You can not add this element on assignment page.');
}
}
Authortool.prototype.addsubelement = function(){
/******************************************************
* Tool for creating a new subelement
* -hint
* -extra
* can be shown in pop-up box or in second page
******************************************************/
var tool = this;
this.openDialog('addsubelement', 'Create new '+this.elemtype, ['bigElem','extratitle','add_elem', 'add_button_bar']); // Localization
var bigboxcheck = this.dialogbox
.find('.bigElem')
.append('<h2>Show on second page</h2><input class="isBigbox" type="checkbox" /><span class="plusinfo">(Default display in pop-up box)</span>').find('.isBigbox');
if (typeof(jQuery.fn.emathonoff) === 'function'){
bigboxcheck.emathonoff({
texts: ['yes','no'],
coloron: 'green',
coloroff: 'red'
});
}
this.dialogbox
.find('.extratitle')
.append('<h2>Title</h2><input class="extratitleinput" type="text"\>');
this.dialogbox
.find('.add_elem')
.append('<h2>'+this.elemtype+' content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_header_button">Header</button><button class="add_displayform_button">Display formula</button><button class="add_derivation_button">Derivation</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button><button class="add_geoeditor_button">GeoEditor</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addsubelement').find('.add_elem').append('<div><textarea class="addElem add_text"></textarea></div>');
}).end()
.find('.add_header_button').click(function(){
jQuery(this).parents('#authordialog_addsubelement').find('.add_elem').append('<div><h3 class="addElem add_header"><span class="mathquill-textbox"></span></h3></div>').find('.mathquill-textbox').last().mathquill('textbox');;
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addsubelement').find('.add_elem').append('<div class="mathdisplaystyle"><span class="addElem add_formula mathquill-editable"></span></div>').find('.mathquill-editable').last().mathquill('editable');
}).end()
.find('.add_derivation_button').click(function(){
var addexelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
var sdnum = addexelem.find('.add_deriv').length;
addexelem.append('<div><div class="addElem add_deriv deriv_'+sdnum+'"></div></div>');
wikify('<<qedderiv '+tool.elemtype+'sd'+sdnum+'>>', addexelem.find('.add_deriv.deriv_'+sdnum)[0]);
}).end()
.find('.add_geoeditor_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
var geoeditornum = addelem.find('.add_geoeditor').length;
addelem.append('<div><div class="addElem add_geoeditor geoeditor_'+geoeditornum+'"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option selected="selected" value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span></div></div>');
wikify('<<geograph '+this.elemtype+'geoeditor_'+geoeditornum+' full author>>', addelem.find('.add_geoeditor.geoeditor_'+geoeditornum)[0]);
addelem.find('input.isSquare').last().change(function(){
var options = {};
options.editable= true;
options.scenes = jQuery(this).parent().parent().find('.grapheditor').geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
jQuery(this).parent().parent().find('.grapheditor').geoeditor('init', options);
});
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
var funcgnro = addelem.find('.add_funcgraph').length;
addelem.append('<div><div class="addElem add_funcgraph exderiv_'+funcgnro+'"></div></div>');
wikify('<<emathfuncgraph funcg'+funcgnro+' authordialog>>', addelem.find('.add_funcgraph.exderiv_'+funcgnro)[0]);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
addelem.append('<div><div class="addElem add_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
var tablenro = addelem.find('.add_table').length;
addelem.append('<div><div class="addElem add_table extable_'+tablenro+'"></div></div>');
wikify('<<emathtable [[table'+tablenro+']] authordialog>>', addelem.find('.add_table.extable_'+tablenro)[0]);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addsubelement').find('.add_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="addElem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();// Testing adding table
this.save = function(){
this.elementdata = {
'ebooktitle': '',
'tags': ('ebook'+this.elemtype+(this.dialogbox.find('.isBigbox').attr('checked')?' bigbox':'')).split(' '),
'content': '',
'data': {},
'fields': {'extraclasses':''}
}
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var elements = this.dialogbox.find('.addElem');
var deriv_number = 0;
var geoeditor_number = 0;
this.elementdata.data.extratitle = this.dialogbox.find('.extratitle input.extratitleinput').val();
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_header')){
this.elementdata.content += '!'+elements.eq(i).find('.mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
} else if (elements.eq(i).hasClass('add_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_geoeditor')){
var sizeParam = 'full';
var sizeValue = elements.eq(i).find('.imageSize').val();
if(elements.eq(i).find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += elements.eq(i).find('.imageFloat').val();
this.elementdata.content += '<<geograph geoeditor'+geoeditor_number+' '+sizeParam+'>>\n'
if (typeof(this.elementdata.data.geoeditors) == 'undefined'){
this.elementdata.data.geoeditors = {};
}
this.elementdata.data.geoeditors['geoeditor'+geoeditor_number] = elements.eq(i).find('.grapheditor').geoeditor('getContent')[0];
geoeditor_number++;
} else if (elements.eq(i).hasClass('add_deriv')){
this.elementdata.content += '<<qedderiv '+tool.elemtype+'sd'+deriv_number+' savehere>>\n';
if (typeof(this.elementdata.data.derivations) == 'undefined'){
this.elementdata.data.derivations = {};
}
var exsdeditor = elements.eq(i).find('.qededitor')[0].editor;
var derdata = exsdeditor.derivation.getSaveData();
for (var j=0; j<derdata.length; j++){
this.elementdata.data.derivations[derdata[j].name] = derdata[j].data;
exsdeditor.deleteDeriv(derdata[j].name);
}
deriv_number++;
} else if (elements.eq(i).hasClass('add_funcgraph')){
this.elementdata.content += '<<emathfuncgraph funcg'+graphcount+'>>\n';
if (typeof(this.elementdata.data.emathfuncgraph) == 'undefined'){
this.elementdata.data.emathfuncgraph = {};
}
this.elementdata.data.emathfuncgraph['funcg'+graphcount] = elements.eq(i).find('.emathfg').emathfuncgraph('get');
graphcount++;
} else if (elements.eq(i).hasClass('add_table')){
this.elementdata.content += '<<emathtable table'+tablecount+'>>\n';
if (typeof(this.elementdata.data.emathtable) == 'undefined'){
this.elementdata.data.emathtable = {};
}
this.elementdata.data.emathtable['table'+tablecount] = elements.eq(i).find('.emathtable').emathtable('get');
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph [[imageplaceholder'+imagecount+']] image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.addElement = function(){
/******************************************************
* Tool for adding element in chapter/section/subsection
******************************************************/
// if (elemtype == undefined){
// return false;
// }
var tool = this;
this.addelemdata = {
'pageview': jQuery('#pageOne > [tiddler]').attr('tiddler'), // chapter/section/subsection, where element is added
'beforeafter': '', // Before or after the reference element
'refelement': '' // The reference element for the place of addition
};
this.adders = {
'tableelement': this.createTableElem,
'examplesd': this.createSd,
'examplegeograph': this.createGeograph,
'examplebox': this.createExample,
'theorybox': this.createTheory,
'history': this.createHistory,
'didyouknow': this.createDidYouKnow,
'textelement': this.createTextelement,
'discussion': this.createDiscussion,
'prerequisites': this.createPrerequisites,
'joinimage': this.joinImageElement,
'copyelement': this.copyElement
};
tool.addelem = tool.adders[tool.elemtype];
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 0){
// var pageElements = jQuery('#pageOne > [tiddler]').addClass('addelems').children('[tiddler]');
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
pageElements.eq(0).prepend('<div class="addelembefore"><a href="javascript:;" title="Add element before">↰+</a></div>').end()
.append('<div class="addelemafter""><a href="javascript:;" title="Add element after">↲+</a></div>')
.find('.addelembefore a, .addelemafter a').click(function(){
tool.addelemdata.beforeafter = 'after';
if (jQuery(this).parent().hasClass('addelembefore')){
tool.addelemdata.beforeafter = 'before'
};
tool.addelemdata.refelement = jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var page = jQuery(this).parents('.addelems').removeClass('addelems').attr('id');
jQuery('.addelembefore, .addelemafter').remove();
tool.addelem();
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('addelems');",30);
if (pageElements.length == 0){
this.addelem();
jQuery('.addelems').removeClass('addelems');
}
} else {
alert('You can not add this element on assignment page.');
}
}
Authortool.prototype.addInTiddler = function(){
/******************************************************
* Tool for adding <<tiddler>>-macro in chapter/section/subsection
******************************************************/
var tiddler = store.getTiddler(this.addelemdata.pageview);
var content = tiddler.text;
var reftiddler = '<<tiddler '+this.addelemdata.refelement+'>>';
var newtiddler = '<<tiddler '+this.tiddlerName+'>>'
if (this.addelemdata.refelement == ''){
content = content + '\n' + newtiddler;
} else if (this.addelemdata.beforeafter == 'before'){
content = content.replace(reftiddler, newtiddler + '\n' + reftiddler);
} else if (this.addelemdata.beforeafter == 'after'){
content = content.replace(reftiddler, reftiddler + '\n' + newtiddler);
}
var now = new Date();
if(!tiddler.fields.emathbookid || tiddler.fields.emathbookid !== EbookPages[0].ebook.bookid){
tiddler.fields.emathbookid = EbookPages[0].ebook.bookid;
}
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now,
null,
null,
tiddler.fields);
autoSaveChanges();
this.sendFifo.push({"title": this.addelemdata.pageview, "newTiddler": 0});
//refreshElements(jQuery('#pageOneWrapper')[0]);
}
//}}}
/***
|Name|author-edit.js|
|Version|1.11|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|Authortools for TiddlyWiki-ebook fuctionality for editing staff in ebook|
!!!!!Revisions
<<<
20131129.2120 ''add'' ''Version 1.11''
* added headimage option to chapters
<<<
<<<
20131203.1313 ''fix'' ''Version 1.10''
* improvments and fixes of new editor for table of content
* tocStructure infobox
<<<
<<<
20131129.2120 ''add'' ''Version 1.9''
* new editor for table of content
<<<
<<<
20131114.1303 ''add'' ''Version 1.8''
* editoption for hint/extra Sderivations
<<<
<<<
20131111.1050 ''add'' ''Version 1.7''
* editoption for otherassignment ebooktitle
* dataobject check for hint/extra edit
<<<
<<<
20131109.1110 ''add'' ''Version 1.6''
* editoption for otherassignment container
<<<
<<<
20131108.1106 ''add'' ''Version 1.5''
* info about extre/hint title
<<<
<<<
20131015.1348 ''fix'' ''Version 1.4''
* modelsolution language check in edit
<<<
<<<
20131009.0922 ''fix'' ''Version 1.3''
* assignment solution translation bug
<<<
<<<
20131008.1343 ''add'' ''Version 1.2''
* Modelsolution edit
<<<
<<<
20130820.1550 ''Version 1.1''
* signchartedit added
<<<
<<<
20130820.1440 ''Version 1.0''
* tranlation editing tool admin addons
<<<
***/
//{{{
/*******************************************************************
* author-edit.js
* Authortools for TiddlyWiki-ebook
* to edit exists content
* Petri Salmela
* Petri Sallasmaa
* 8.11.2011
* depends: jQuery, jQueryUI
*******************************************************************/
Authortool.prototype.markChapterType = function(currentLi,ulToclevel,currentPage){
var pageTypeclasses =[];
var pageExtraclasses =[];
var pageType="";
if(currentPage.pagetype){
pageTypeclasses.push(currentPage.pagetype);
pageType = currentPage.pagetype;
currentLi.data('headimage',currentPage.headimage);
}else{
switch(ulToclevel){
case 0:
pageTypeclasses.push('frontpage');
pageType = 'frontpage';
break;
case 1:
pageTypeclasses.push('chapter');
pageType = 'chapter';
currentLi.data('headimage',currentPage.headimage);
break;
case 2:
pageTypeclasses.push('section');
pageType = 'section';
break;
case 3:
if(store.getTiddlerText(currentPage.content,'').indexOf('ebook_assignmentlist') !== -1){
pageTypeclasses.push('assignments');
pageType = 'assignments';
}else{
pageTypeclasses.push('text');
pageType = 'text';
}
break;
default:
break;
}
}
currentLi.attr('pagetype',pageType);
currentLi.data('pagetype',pageType);
if(currentPage.extra){
currentLi.addClass(currentPage.extra);
}
currentLi.children('a').prepend('<span title="'+EbookDictionary.localize(pageType)+'" data-empagetype="'+pageType+'" class="'+pageTypeclasses.join(' ')+'"></span>');
for(var i=0;i<currentPage.types.length;i++){
if(currentPage.types[i] !==pageType){
pageExtraclasses.push(currentPage.types[i]);
currentLi.data('is'+currentPage.types[i],true);
}
}
currentLi.data('elementstypes',currentPage.types);
currentLi.children('a').append('<span class="pageextraclasses"><span>');
for(var i=0; i < pageExtraclasses.length;i++){
currentLi.children('a').find('.pageextraclasses').append('<span title="'+EbookDictionary.localize(pageExtraclasses[i])+'" class="'+pageExtraclasses[i]+'"></span>');
}
}
Authortool.prototype.getTocTitle = function(listLi, lang){
if(typeof(lang) ==="undefined"){
if(listLi.data('currentTitle'+EbookPages[0].currentlang)){
var currentTitle = listLi.data('currentTitle'+EbookPages[0].currentlang);
}else{
var currentTitle = (
EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')]
&& EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles
&&EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles[EbookPages[0].currentlang]
?EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles[EbookPages[0].currentlang]
: EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].title
? EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].title
: EbookDictionary.localize('title')
);
}
}else{
if(listLi.data('currentTitle'+lang)){
var currentTitle = listLi.data('currentTitle'+lang);
}else{
var currentTitle = (
EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')]
&& EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles
&&EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles[lang]
?EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].alttitles[lang]
: EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].title
? EbookPages[0].ebook.tocdict[listLi.attr('data-emchapid')].title
: EbookDictionary.localize('title')
);
}
}
return currentTitle;
}
Authortool.prototype.fillTocitemDialog = function(dialog){
var tool=this;
var dialogOptions={};
var listLi = dialog.data('listLi');
var bookLanguages = EbookPages[0].ebook.getLangs();
dialog.find('.tocTitle').append('<h3>'+EbookDictionary.localize('title')+'</h3><div class="langSelect"></div>');
for(var i=0;i<bookLanguages.length;i++){
dialog.find('.tocTitle .langSelect').append('<input type="radio" '+(bookLanguages[i] == EbookPages[0].currentlang?'checked="checked" ':'')+'name="titleLang" id="titleLang'+bookLanguages[i]+'" value="'+bookLanguages[i]+'"/><label for="titleLang'+bookLanguages[i]+'">'+bookLanguages[i]+'</label>');
}
var currentTitle = this.getTocTitle(listLi);
dialog.find('.tocTitle').append('<span>'+EbookDictionary.localize('title')+'</span><input type="text" name="currentTitle" value="'+currentTitle+'"/>');
var additionalTypeslist = ["theory","example","noheader","topic"];
if(listLi.attr('data-emtoclevel') ==="3" && listLi.attr('data-emchapid') ==="newchap"){
dialog.find('.tocparameters').append('<div class="subTypes"><h3>'+EbookDictionary.localize('subsectiontype')+'</h3><input type="radio" name="subType" id="subTypeAssignment" '+(listLi.data('pagetype')&&listLi.data('pagetype')==="assignments"?'checked="checked" ':'')+'value="assignments"/><label for="subTypeAssignment">'+EbookDictionary.localize('assignments')+'</label><input type="radio" name="subType" id="subTypeText" '+(listLi.data('pagetype')&&listLi.data('pagetype')==="text"?'checked="checked" ':'')+'value="text"/><label for="subTypeText">'+EbookDictionary.localize('textpage')+'</label><div class="fillMeMessage">'+EbookDictionary.localize('select type')+'</div></div>');
}
var additionalTypes = '<div style="display:none;" class="additionalTypes">';
for(var i=0;i< additionalTypeslist.length;i++){
additionalTypes +='<input class="additionalcheckbox" type="checkbox" id="is'+additionalTypeslist[i]+'" '+(listLi.data('is'+additionalTypeslist[i])?'checked="checked" ':'')+'><label for="is'+additionalTypeslist[i]+'">'+EbookDictionary.localize(additionalTypeslist[i])+'</label>';
}
additionalTypes +='</div>';
dialog.find('.tocparameters').append(additionalTypes);
if(listLi.attr('pagetype') ==="text"){dialog.find('.additionalTypes').show();}
if(listLi.attr('data-emtoclevel') !="0"){
dialog.find('.tocparameters').append('<h3>'+EbookDictionary.localize('parameters')+'</h3><div class="isextra"><input type="checkbox" name="isextra" id="isextramaterial" '+(listLi.data('isextramaterial')?'checked="checked" ':'')+'><label for="isextramaterial">'+EbookDictionary.localize('is extramaterial')+'</label></div>');
}
if(listLi.attr('data-emtoclevel') ==="1"){
var headimageTiddlers = store.getTaggedTiddlers('headimage');
if(headimageTiddlers.length > 0){
dialogOptions['width'] = "800px";
dialog.find('.tocparameters').after('<div class="imgselect"><h3>'+EbookDictionary.localize('headimage')+'</h3><div class="selectheadimage"><div class="imageAddList"></div><div class="imageAddPreview"></div></div></div>');
var currentHeadimage = listLi.data('headimage')
var imageAddList = dialog.find('.imgselect .imageAddList');
var imageAddPreview = dialog.find('.imgselect .imageAddPreview');
var imageTiddlersHtmlList='<ul id="addimagelist">\n';
imageTiddlersHtmlList += '<li imageTiddler="" tiddlerIndex="-1">'+EbookDictionary.localize('no headimage')+'</li>\n';
for(var i=0;i<headimageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+headimageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(headimageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
var imageList = imageAddList.append(imageTiddlersHtmlList).find('#addimagelist');
imageList.find('li[imageTiddler="'+currentHeadimage+'"]').addClass('previewed');
if(currentHeadimage){
wikify('[img['+currentHeadimage+']]',imageAddPreview[0]);
}else{
imageAddPreview.append('<h3 style="margin-top:4em;">'+EbookDictionary.localize('no headimage')+'</h3>')
}
imageList.find('li').click(function(){
var thisLi = jQuery(this);
if(!thisLi.hasClass('previewed')){
var thisTitle = thisLi.attr('imageTiddler');
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
imageAddPreview.html('');
listLi.data('headimage',thisTitle);
if(thisTitle){
wikify('[img['+thisTitle+']]',imageAddPreview[0]);
}else{
imageAddPreview.append('<h3>'+EbookDictionary.localize('no headimage')+'</h3>')
}
}
});
}else{
dialog.find('.tocparameters').after('<div class="imgselect"><h3>'+EbookDictionary.localize('no headimages available')+'</h3></div>');
}
}
/********************
*Handlers for inputs*
********************/
dialog.delegate('input[name="titleLang"]','change',function(){
var changedTitle = tool.getTocTitle(listLi, jQuery(this).val());
dialog.find('input[name="currentTitle"]').val(changedTitle);
});
dialog.delegate('input[name="currentTitle"]','change',function(){
var selectedLanguage = dialog.find('input[name="titleLang"]:checked').val();
var inputsText = jQuery(this).val();
listLi.data('isChanged',true);
listLi.data('currentTitle'+selectedLanguage,inputsText);
if(selectedLanguage===EbookPages[0].currentlang){
listLi.children('a').find('.emtoctitle').html(inputsText);
}
});
dialog.delegate('#isextramaterial','change',function(){
listLi.data('isChanged',true);
listLi.data('isextramaterial',jQuery(this).is(':checked'));
if(jQuery(this).is(':checked') && listLi.children('a').find('span.pageextraclasses .extramaterial').length ==0){
listLi.children('a').find('span.pageextraclasses').append('<span title="'+EbookDictionary.localize('extramaterial')+'" class="extramaterial"></span>');
}else{
listLi.children('a').find('span.pageextraclasses .extramaterial').remove();
}
});
dialog.delegate('input.additionalcheckbox','change',function(){
listLi.data('isChanged',true);
listLi.data(jQuery(this).attr('id'),jQuery(this).is(':checked'));
if(jQuery(this).is(':checked') && listLi.children('a').find('span.pageextraclasses .'+jQuery(this).attr('id').replace('is','')).length ==0){
listLi.children('a').find('span.pageextraclasses').append('<span title="'+EbookDictionary.localize(jQuery(this).attr('id').replace('is',''))+'" class="'+jQuery(this).attr('id').replace('is','')+'"></span>');
if(listLi.data('elementstypes')){
listLi.data('elementstypes').push(jQuery(this).attr('id').replace('is',''));
}else{
listLi.data('elementstypes')=[jQuery(this).attr('id').replace('is','')];
}
}else{
listLi.children('a').find('span.pageextraclasses .'+jQuery(this).attr('id').replace('is','')).remove();
if(listLi.data('elementstypes')){
listLi.data('elementstypes').remove(jQuery(this).attr('id').replace('is',''));
}
}
});
dialog.delegate('input[name="subType"]','change',function(event){
var notselected = dialog.find('input[name="subType"]:not(:checked)');
for(var i = 0;i<notselected.length;i++){
listLi.find('span[data-empagetype="'+notselected.eq(i).val()+'"]').remove();
}
var selectedtype = dialog.find('input[name="subType"]:checked').val();
listLi.children('a').prepend('<span data-empagetype="'+selectedtype+'" title="'+EbookDictionary.localize(selectedtype)+'"class="'+selectedtype+'"></span>')
listLi.data('isChanged',true);
listLi.data('pagetype',selectedtype);
listLi.attr('pagetype',selectedtype);
jQuery('#itemdialog').find('.subTypes').removeClass('fillMe');
if(listLi.attr('pagetype') ==="text"){dialog.find('.additionalTypes').show();}else{dialog.find('.additionalTypes').hide();}
});
return dialogOptions;
}
Authortool.prototype.fillBookSettings = function(dialog){
var tool=this;
var thisplace = jQuery('#booktitleedit').parent();
var bookLanguages = EbookPages[0].ebook.getLangs();
dialog.find('.bookTitle').append('<h3>'+EbookDictionary.localize('booktitle')+'</h3><div class="langSelect"></div>');
for(var i=0;i<bookLanguages.length;i++){
dialog.find('.bookTitle .langSelect').append('<input type="radio" '+(bookLanguages[i] == EbookPages[0].currentlang?'checked="checked" ':'')+'name="titleLang" id="titleLang'+bookLanguages[i]+'" value="'+bookLanguages[i]+'"/><label for="titleLang'+bookLanguages[i]+'">'+bookLanguages[i]+'</label>');
}
var getCurrentTitle = function(lang){
return (thisplace.data('alttitles')[lang]?thisplace.data('alttitles')[lang]:thisplace.data('title'));
}
dialog.find('.bookTitle').append('<span>'+EbookDictionary.localize('title')+'</span><input type="text" name="currentTitle" value="'+getCurrentTitle(EbookPages[0].currentlang)+'"/>');
var authors = dialog.find('.bookparameters').append('<div id="bookAuthors"><h3>'+EbookDictionary.localize('bookauthors')+'</h3><ul></ul></div>').find('#bookAuthors ul');
for(var i=0;i<thisplace.data('author').length;i++){
authors.append('<li><input class="authorinput" type="text" value="'+thisplace.data('author')[i]+'"/><span class="removeAuthor">x</span></li>');
}
var secauthors = dialog.find('.bookparameters').append('<div id="bookSecAuthors"><h3>'+EbookDictionary.localize('booksecondaryauthors')+'</h3><ul class="authorgroups"></ul></div>').find('#bookSecAuthors ul');
for(var i=0;i<thisplace.data('secauthor').length;i++){
var groupname = thisplace.data('secauthor')[i].name;
secauthors.append('<li><input class="groupname" type="text" value="'+groupname+'"/><span class="removeSecgroup">x</span><ul groupname="'+groupname+'"></ul></li>');
for(var j=0;j<thisplace.data('secauthor')[i]['author'].length;j++){
secauthors.find('ul[groupname="'+groupname+'"]').append('<li><input type="text" value="'+thisplace.data('secauthor')[i]['author'][j]+'"/><span class="removeSecAuthor">x</span></li>');
}
}
var updateSecAuthors = function(){
var grouplist =[];
var groups = jQuery('#bookSecAuthors .authorgroups').children('li');
for(var i=0;i<groups.length;i++){
if(groups.eq(i).children('input.groupname').length === 1){
var group = {};
group['name']=groups.eq(i).children('input.groupname').val();
var authors = groups.eq(i).find('input:not(.groupname)');
var authorlist = [];
for(var j=0;j<authors.length;j++){
if(authors.eq(j).val() !==""){
authorlist.push(authors.eq(j).val());
}
}
group['author']=authorlist;
grouplist.push(group);
}
}
thisplace.data('secauthor',grouplist);
}
var updateAuthors = function(){
var authors = jQuery('#bookAuthors .authorinput');
var authorlist = [];
for(var i=0;i<authors.length;i++){
if(authors.eq(i).val() !==""){
authorlist.push(authors.eq(i).val());
}
}
thisplace.data('author',authorlist);
}
/********************
*Handlers for inputs*
********************/
dialog.delegate('input[name="titleLang"]','change',function(){
var changedTitle = getCurrentTitle( jQuery(this).val());
dialog.find('input[name="currentTitle"]').val(changedTitle);
});
dialog.delegate('input[name="currentTitle"]','change',function(){
var selectedLanguage = dialog.find('input[name="titleLang"]:checked').val();
var inputsText = jQuery(this).val();
if(selectedLanguage === EbookPages[0].ebook.defaultlang){
thisplace.data('title',inputsText);
}else{
thisplace.data('alttitles')[selectedLanguage] = inputsText;
}
});
//dialog.delegate('#isextramaterial','change',function(){}
dialog.delegate('#bookAuthors .authorinput','change',function(){
updateAuthors();
});
dialog.delegate('#bookAuthors li,#bookSecAuthors li','click',function(event){
event.preventDefault();
event.stopPropagation();
});
dialog.delegate('#bookAuthors ul','click',function(event){
jQuery('#bookAuthors ul').append('<li><input class="authorinput" type="text" value=""/><span class="removeAuthor">x</span></li>');
});
dialog.delegate('#bookAuthors .removeAuthor','click',function(event){
jQuery(this).parent().children('input').remove();
updateAuthors();
event.preventDefault();
event.stopPropagation();
jQuery(this).parent().remove();
});
dialog.delegate('#bookSecAuthors ul','click',function(event){
if(jQuery(this).hasClass('authorgroups')){
jQuery(this).append('<li><input class="groupname" type="text" value=""/><span class="removeSecgroup">x</span><ul groupname=""></ul></li>');
}else{
jQuery(this).append('<li><input type="text" value=""/><span class="removeSecAuthor">x</span></li>');
}
});
dialog.delegate('#bookSecAuthors input','change',function(){
updateSecAuthors();
});
dialog.delegate('#bookSecAuthors .removeSecgroup','click',function(event){
jQuery(this).parent().children('input').remove();
jQuery(this).parent().children('ul').remove();
updateSecAuthors();
event.preventDefault();
event.stopPropagation();
jQuery(this).parent().remove();
});
dialog.delegate('#bookSecAuthors .removeSecAuthor','click',function(event){
jQuery(this).parent().children('input').remove();
updateSecAuthors();
event.preventDefault();
event.stopPropagation();
jQuery(this).parent().remove();
});
}
Authortool.prototype.addTocItem = function(setPlace,thisLevel,type){
var tool = this;
if(typeof(type)==="undefined"){
if(thisLevel ===1){
type = "chapter";
}else if(thisLevel ===2){
type = "section";
}else {
type = "subsection";
}
}
setPlace.append('<li newtype="'+type+'" pagetype="'+type+'" class="emtoc-item'+( thisLevel > 2 ? ' emtoc-hiddensubs' : '' )+'" data-emchapid="newchap" data-emtoclevel="'+thisLevel +'">\n<a href="javascript:;"><span '+( thisLevel < 3 ? 'title="'+EbookDictionary.localize(type)+'" data-empagetype="'+type+'" class="'+type+'"' : '' )+'></span><span class="emtoctitle">'+EbookDictionary.localize('new '+type,0)+'</span><span class="pageextraclasses"><span>\n<span class="removeTocItem" ><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" title="'+EbookDictionary.localize('remove')+'" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg></span>\n</a>\n'+( thisLevel < 3 ? '<ul toclevel="'+(thisLevel + 1)+'" class="emtoc-chapterlist lastAddedChapterlist" data-emchaplist="newchap">\n</ul>\n' : '' )+'</li>\n');
if(thisLevel < 3){
var lastAddedChapterlist = setPlace.find('.lastAddedChapterlist');
lastAddedChapterlist.removeClass('lastAddedChapterlist').sortable();
lastAddedChapterlist.sortable({ connectWith: '#tocStructureEdit ul[toclevel="'+(thisLevel + 1)+'"]' });
}
if(thisLevel > 1){
if(setPlace.parent().children('span.emtoc-closethis').length ===0){
setPlace.parent().prepend('<span class="emtoc-closethis">'+tool.tocicons.minusclose+'</span><span class="emtoc-openthis">'+tool.tocicons.plusopen+'</span>');
}
}
var liToSet = setPlace.children('li').last();
var availableLangs = EbookPages[0].ebook.getLangs();
for(var i=0;i<availableLangs.length;i++){
liToSet.data('currentTitle'+availableLangs[i],EbookDictionary.localize('new '+type,availableLangs[i]));
}
liToSet.data('isChanged',true);
}
Authortool.prototype.editTocStructure = function(){
/******************************************************
* Tool for editing structure of tableofcontent
******************************************************/
var tool=this;
tool.tocicons = {
plusopen: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" viewbox="0 0 30 30" class="mini-icon mini-icon-plusopen"> <path style="stroke: none;" d="M2 8 a6 6 0 0 1 6 -6 l14 0 a6 6 0 0 1 6 6 l0 14 a6 6 0 0 1 -6 6 l-14 0 a6 6 0 0 1 -6 -6z m2 0 l0 14 a4 4 0 0 0 4 4 l14 0 a4 4 0 0 0 4 -4 l0 -14 a4 4 0 0 0 -4 -4 l-14 0 a4 4 0 0 0 -4 4z M13 7 l4 0 l0 6 l6 0 l0 4 l-6 0 l0 6 l-4 0 l0 -6 l-6 0 l0 -4 l6 0z" /></svg>',
minusclose: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" viewbox="0 0 30 30" class="mini-icon mini-icon-minusclose"> <path style="stroke: none;" d="M2 8 a6 6 0 0 1 6 -6 l14 0 a6 6 0 0 1 6 6 l0 14 a6 6 0 0 1 -6 6 l-14 0 a6 6 0 0 1 -6 -6z m2 0 l0 14 a4 4 0 0 0 4 4 l14 0 a4 4 0 0 0 4 -4 l0 -14 a4 4 0 0 0 -4 -4 l-14 0 a4 4 0 0 0 -4 4z M7 13 l16 0 l0 4 l-16 0 l0 -4z" /></svg>'
};
var buttonset =[
{
name: 'savetocedit',
text: EbookDictionary.localize('save', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="25" height="25" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-savedoc-color"> <path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="blue" style="stroke: none;" d="M12 14 l22 0 l4 4 l0 22 l-26 0z m6 2 l0 7 l14 0 l0 -7z m9 1 l3 0 l0 5 l-3 0z m-12 9 l0 12 l20 0 l0 -12z" transform="scale(0.8 0.8)" /></svg>',
click: function(event){
jQuery(this).trigger('tocEdit-save');
}
},
{
name: 'canceltocedit',
text: EbookDictionary.localize('cancel', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="25" height="25" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg>',
click: function(event){
jQuery(this).trigger('tocEdit-cancel');
}
},
{
name: 'toceditinfo',
text: EbookDictionary.localize('toceditinfo', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="25" height="25" title="info" viewbox="0 0 30 30" class="mini-icon mini-icon-info"><path style="stroke: none; fill: #00a;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: #00c; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M12 12 l6 0 l0 12 l-6 0 l0 -12 z" /><circle style="fill: white; stroke: none;" cx="15" cy="8" r="3" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg>',
click: function(event){
jQuery(this).trigger('tocEdit-info');
}
}
];
var place = jQuery('body').append('<div id="tocStructureEdit"><div class="tocEditor"></div></div>').find('#tocStructureEdit');
var options = {};
options.tocdata = EbookPages[0].ebook.tocObject();
options.lang = EbookPages[0].currentlang;
place.find('.tocEditor').emathtocapp(options);
for (var j = 0; j < buttonset.length; j++) {
var butContent = buttonset[j].icon || buttonset[j].text;
var button = jQuery('<span class="'+buttonset[j].name+' emtoc-button" title="'+buttonset[j].text+'">'+butContent+'</span>');
button.bind('click', {}, buttonset[j].click);
place.find('.tocEditor .emtoc-headbar .emtoc-buttonbar').append(button);
}
jQuery('#tocStructureEdit .tocEditor')
.undelegate('li.emtoc-item a', 'click')
.delegate('li.emtoc-item a', 'click', function(event){
var itemDialog = place.append('<div id="itemdialog" title="'+EbookDictionary.localize('toc item settigns')+'"><div class="tocTitle"></div><div class="tocparameters"></div></div>').find('#itemdialog');
itemDialog.data('listLi',jQuery(this).parents('li').eq(0));
var extradialogOptions = tool.fillTocitemDialog(itemDialog);
var dialogOptions = {
modal:true,
buttons : [
{
text:EbookDictionary.localize('ok'),
click: function(){
if(jQuery('#itemdialog').find('.subTypes').length ===1 &&jQuery('#itemdialog').find('.subTypes input[name="subType"]:checked').length ===0){
jQuery('#itemdialog').find('.subTypes').addClass('fillMe');
return false;
}
jQuery('#itemdialog').dialog("destroy").remove();
}
}
]
};
jQuery.extend(true,dialogOptions,extradialogOptions);
itemDialog.dialog(dialogOptions);
event.preventDefault();
return false;
});
var booksTitle =
place.find('h1.emtoc-title')
.html('<span id="booktitleedit">'+ jQuery('#tocStructureEdit h1.emtoc-title').text()+'</span>')
.data('title',options.tocdata.title)
.data('alttitles',options.tocdata.alttitles)
.data('author',options.tocdata.author)
.data('secauthor',options.tocdata.secondaryauthor);
/***************************
** Insert remove buttons ***
***************************/
tool.currentChapIds = [];
tool.removedChapIds = [];
var currentPage = EbookPages[0].ebook.tocdict['front'];
var currentChapId = currentPage.chapid;
while(currentChapId){
tool.currentChapIds.push(currentChapId);
var currentLi = place.find('li[data-emchapid="'+currentChapId+'"]');
var ulToclevel = parseInt(currentLi.parent().attr('toclevel'));
tool.markChapterType(currentLi,ulToclevel,currentPage);
if(parseInt(ulToclevel) > 0 && parseInt(ulToclevel) < 3 && currentPage.chapters && currentPage.chapters.length === 0 && currentLi.children('ul').length === 0){
currentLi.append('<ul toclevel = "'+(parseInt(ulToclevel) + 1)+'" class="emtoc-chapterlist" data-emchaplist="'+currentPage.chapid+'">');
}
if(EbookPages[0].ebook.isEmptyById(currentChapId)){
place.find('li[data-emchapid="'+currentChapId+'"] a').append('<span class="removeTocItem" ><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" title="'+EbookDictionary.localize('remove')+'" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg></span>');
}
if(currentPage.next){
currentPage=EbookPages[0].ebook.tocdict[currentPage.next];
currentChapId = currentPage.chapid;
}else{
currentChapId =false;
}
}
place.find('ul[toclevel="1"]').sortable({ connectWith: '#tocStructureEdit ul[toclevel="1"]' });
place.find('ul[toclevel="2"]').sortable({ connectWith: '#tocStructureEdit ul[toclevel="2"]' });
place.find('ul[toclevel="3"]').sortable({ connectWith: '#tocStructureEdit ul[toclevel="3"]' });
place.find('.emtoc-search').remove();
/**********************
***Infotable ***
**********************/
var infoTableTypes = ["frontpage","chapter","section","text","assignments","theory","noheader","example","extramaterial","topic"];
var infotable = jQuery('.toceditinfo').append('<div id="tocinfobox"><span class="closeTocinfo"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" title="'+EbookDictionary.localize('close')+'" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg></span><table></table></div>').find('#tocinfobox table');
infotable.append('<tr><th>'+EbookDictionary.localize('tocicon')+'</th><th>'+EbookDictionary.localize('icon definition')+'</th></tr>');
for(var i=0;i<infoTableTypes.length;i++){
infotable.append('<tr><td><span class="'+infoTableTypes[i]+'"></span></td><td><span class="infotext">'+EbookDictionary.localize(infoTableTypes[i])+'</span></td></tr>');
}
/**********************
***Sort handlers ***
**********************/
place.delegate('ul[toclevel]', "sortupdate", function( event, ui ) {
if(jQuery(this).children('li').length===1 ){
jQuery(this).parent().children('a').find('.removeTocItem').remove();
jQuery(this).parent().prepend('<span class="emtoc-closethis">'+tool.tocicons.minusclose+'</span><span class="emtoc-openthis">'+tool.tocicons.plusopen+'</span>');
};
event.stopPropagation();
});
place.delegate('ul[toclevel]', "sortbeforestop", function( event, ui ) {
if(jQuery(this).children('li').length ===0){
var thisParentLi = jQuery(this).parent();
thisParentLi.children('span.emtoc-closethis').remove();
thisParentLi.children('span.emtoc-openthis').remove();
var parentChapid = thisParentLi.attr('data-emchapid');
if(parentChapid === 'newchap' || EbookPages[0].ebook.isEmptyById(parentChapid) ){
if(thisParentLi.find('a .removeTocItem').length ===0){
thisParentLi.find('a').append('<span class="removeTocItem" ><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" title="'+EbookDictionary.localize('remove')+'" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg></span>');
}
}
}
event.stopPropagation();
} );
/*******************************************
* tocStructure add handler *
*******************************************/
place.delegate('ul','click',function(event){
var clickedUl = jQuery(this);
var thisLevel = parseInt(clickedUl.attr('toclevel'));
clickedUl.parents('li').eq(0).children('a').find('.removeTocItem').remove();
tool.addTocItem(clickedUl,thisLevel);
if(thisLevel === 3){
clickedUl.children('li').find('a').last().click();
}
event.preventDefault();
return false;
});
place.delegate('li','click',function(event){
event.preventDefault();
return false;
});
place.delegate('#booktitleedit','click',function(event){
var itemDialog = place.append('<div id="booksettingsdialog" title="'+EbookDictionary.localize('book settigns')+'"><div class="bookTitle"></div><div class="bookparameters"></div></div>').find('#booksettingsdialog');
// itemDialog.data('listLi',jQuery(this).parents('li').eq(0));
tool.fillBookSettings(itemDialog);
itemDialog.dialog({
modal:true,
width: 700,
buttons : {
"ok": function(){
jQuery('#booksettingsdialog').dialog("destroy").remove();
}
}
});
});
/*******************************************
* tocStructure remove button click handler *
*******************************************/
place.find('.tocEditor').delegate('li.emtoc-item a .removeTocItem','click',function(event){
if(confirm(EbookDictionary.localize('areyousure'))){
tool.currentChapIds.push(jQuery(this).parent().attr('data-emchapid'));
tool.currentChapIds.remove(jQuery(this).parent().attr('data-emchapid'));
if(jQuery(this).parents('ul').eq(0).find('li').length === 1){
var thisParentLi = jQuery(this).parents('ul').eq(0).parent();
var parentChapid = thisParentLi.attr('data-emchapid');
thisParentLi.children('span.emtoc-closethis').remove();
thisParentLi.children('span.emtoc-openthis').remove();
if(parentChapid === 'newchap' ||jQuery(this).parents('ul').eq(0).children('li').length === 1 || EbookPages[0].ebook.isEmptyById(parentChapid)){
thisParentLi.find('a').append('<span class="removeTocItem" ><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" title="'+EbookDictionary.localize('remove')+'" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg></span>');
}
}
jQuery(this).parents('li').eq(0).remove();
}
event.preventDefault();
event.stopPropagation();
return false;
});
/************************************
* tocStructure info button click *
*************************************/
place.unbind('tocEdit-info').bind('tocEdit-info',function(){
jQuery('#tocinfobox').toggleClass('shown');
});
/************************************
* tocStructure cancel button click *
*************************************/
place.unbind('tocEdit-cancel').bind('tocEdit-cancel',function(){
tool.workingDialog(EbookDictionary.localize('saving'));
jQuery('#tocStructureEdit').remove();
tool.callFifo = [];
tool.callFifo.push('removeLockType');
tool.callFifo.push('removeworkingDialog');
tool.callNext();
});
/************************************
* tocStructure save button click *
*************************************/
place.unbind('tocEdit-save').bind('tocEdit-save',function(){
tool.workingDialog(EbookDictionary.localize('saving'));
var thisTocList = jQuery('#tocStructureEdit ul[toclevel="0"]');
var booktoc = {};
var generatedChapid = 0;
/*General book information*/
booktoc.bookid = EbookPages[0].ebook.bookid;
booktoc.title = booksTitle.data('title') || '';
booktoc.alttitles = booksTitle.data('alttitles') || {};
booktoc.curriculum = options.tocdata.curriculum || '';
booktoc.updateURL = options.tocdata.updateURL || '';
booktoc.lang = options.tocdata.lang || '';
booktoc.altlangs = options.tocdata.altlangs || [];
booktoc.author = booksTitle.data('author') || '';
booktoc.secondaryauthor = booksTitle.data('secauthor') || '';
if (booktoc.altlangs.length == 1 && booktoc.altlangs[0] == ''){
booktoc.altlangs = [];
}
booktoc.style = options.tocdata.style || '';
booktoc.frontpage = {};
var frontTitles = tool.getTitles(thisTocList.children('li'));
booktoc.frontpage.title = frontTitles.title || 'Frontpage';
booktoc.frontpage.alttitles = frontTitles.alttitles || {};
booktoc.frontpage.chapid = options.tocdata.frontpage.chapid || 'front';
booktoc.frontpage.types = ["front"];
booktoc.frontpage.content = options.tocdata.frontpage.content;
booktoc.frontpage.chapters = [];
var chapters = thisTocList.children('li').children('ul').children('li');
for (var i = 0; i<chapters.length; i++){
var chapter = {};
var chapterTitles = tool.getTitles(chapters.eq(i));
chapter.pagetype = 'chapter';
chapter.title = (chapterTitles.title || '').trim();
chapter.alttitles = chapterTitles.alttitles || {};
chapter.types = chapters.eq(i).data('elementstypes') || ["chapter"];
chapter.headimage = chapters.eq(i).data('headimage') || "";
if(chapter.types.indexOf('chapter') === -1){
chapter.types.push('chapter');
}
chapter.extra = chapters.eq(i).data('isextramaterial') || false;
var liChapid= chapters.eq(i).attr('data-emchapid');
if(liChapid === "newchap"){
while(EbookPages[0].ebook.tocdict[tool.getChapidletters(generatedChapid)]){
generatedChapid +=1;
}
chapter.chapid = tool.getChapidletters(generatedChapid);
generatedChapid +=1;
chapter.content = tool.newChapcontent('chapter',false);
}else{
chapter.chapid = liChapid;
chapter.content = EbookPages[0].ebook.tocdict[liChapid].content;
}
chapter.chapters = [];
var sections = chapters.eq(i).children('ul').children('li');
for (var j = 0; j<sections.length; j++){
var section = {};
chapterTitles = tool.getTitles(sections.eq(j));
section.title = (chapterTitles.title || '').trim();
section.alttitles = chapterTitles.alttitles || {};
section.pagetype = 'section';
section.types = sections.eq(j).data('elementstypes') || ["section"];
if(section.types.indexOf('section') === -1){
section.types.push('section');
}
section.extra = sections.eq(j).data('isextramaterial') || false;
var liChapid= sections.eq(j).attr('data-emchapid');
if(liChapid === "newchap"){
while(EbookPages[0].ebook.tocdict[tool.getChapidletters(generatedChapid)]){
generatedChapid++;
}
section.chapid = tool.getChapidletters(generatedChapid);
generatedChapid++;
section.content = tool.newChapcontent('section',false);
}else{
section.chapid = liChapid;
section.content = EbookPages[0].ebook.tocdict[liChapid].content;
}
section.chapters = [];
var subsections = sections.eq(j).children('ul').children('li');
for (var k = 0; k<subsections.length; k++){
var subsection = {};
chapterTitles = tool.getTitles(subsections.eq(k));
subsection.title = (chapterTitles.title || '').trim();
subsection.alttitles = chapterTitles.alttitles || {};
subsection.pagetype = subsections.eq(k).attr('pagetype');
subsection.types = subsections.eq(k).data('elementstypes') || ["subsection"];
if(subsection.types.indexOf('subsection') === -1){
subsection.types.push('subsection');
}
if(subsection.pagetype ==="assignments" && subsection.types.indexOf('assignments') === -1){
subsection.types.push('assignments');
}
subsection.extra = subsections.eq(k).data('isextramaterial') || false;
var liChapid= subsections.eq(k).attr('data-emchapid');
if(liChapid === "newchap"){
while(EbookPages[0].ebook.tocdict[tool.getChapidletters(generatedChapid)]){
generatedChapid++;
}
subsection.chapid = tool.getChapidletters(generatedChapid);
generatedChapid++;
subsection.content = tool.newChapcontent('subsection',subsection.pagetype ==="assignments");
}else{
subsection.chapid = liChapid;
subsection.content = EbookPages[0].ebook.tocdict[liChapid].content;
}
subsection.chapters = [];
section.chapters.push(subsection);
}
chapter.chapters.push(section);
}
booktoc.frontpage.chapters.push(chapter);
}
var tocTiddler = store.getTiddler(EbookPages[0].ebook.bookid+'_toc')
tocTiddler.set(null,'<<showData>>\n<data>{"booktoc":'+JSON.stringify(booktoc)+'}</data>',config.options.txtUserName,new Date());
tool.sendFifo.push({"title": tocTiddler.title, "newTiddler": 0});
bookshelf.init();
EbookPages[0].setBook(bookshelf.getBook(EbookPages[0].ebook.bookid));
EbookPages[1].setBook(bookshelf.getBook(EbookPages[1].ebook.bookid));
jQuery('#tocStructureEdit').remove();
tool.callNext();
});
}
Authortool.prototype.newChapcontent = function(elemtype,assignment){
if(assignment){
var assignmentlist = this.findFreeTiddler('ebook_assignmentlist');
var newAssignmentlist = store.createTiddler(assignmentlist);
newAssignmentlist.set(assignmentlist,'<<otherassignmentAccordion>>\n<<assignmentAccordion>>',config.options.txtUserName,null,'assignmentlist container',null,{'emathbookid':EbookPages[0].ebook.bookid},config.options.txtUserName);
this.sendFifo.push({"title": assignmentlist, "newTiddler": 1});
}
var content = this.findFreeTiddler(elemtype);
var newTiddler = store.createTiddler(content);
newTiddler.set(content,(typeof(assignmentlist) === "undefined"?'':'<<ebookbox [['+assignmentlist+']] assignmentlist>>'),config.options.txtUserName,null,elemtype+' container'+(assignment ? ' assignments':''),null,{'emathbookid':EbookPages[0].ebook.bookid},config.options.txtUserName);
this.sendFifo.push({"title": content, "newTiddler": 1});
return content;
}
Authortool.prototype.getChapidletters = function(index,rest){
if(typeof(rest)==="undefined") {rest = "";}
var characters = 'abcdefghijklmnopqrstuvwxyz';
if(index/26 >1){
return this.getChapidletters(parseInt(index/26)-1,characters[index%26]+rest)
}else if(index/26 ==1){
return 'aa'+rest
}else{
return characters[index%26]+rest
}
}
Authortool.prototype.getTitles = function(currentLi){
var tocElement = EbookPages[0].ebook.tocdict[currentLi.attr('data-emchapid')];
if(!currentLi.data('isChanged')){
return {'title':tocElement.title,"alttitles":tocElement.alttitles};
}else{
var returnAlt = {};
for(var i=0;i<EbookPages[0].ebook.altlangs.length;i++){
returnAlt[EbookPages[0].ebook.altlangs[i]] = currentLi.data('currentTitle'+EbookPages[0].ebook.altlangs[i]) || tocElement.alttitles[EbookPages[0].ebook.altlangs[i]];
}
return {'title':currentLi.data('currentTitle'+EbookPages[0].ebook.defaultlang) || tocElement.title,"alttitles":returnAlt};
}
}
Authortool.prototype.editToc = function(){
this.tocedit(EbookPages[0].ebook.bookid);
}
Authortool.prototype.openAccordian= function(){
jQuery('#pageOne h3[tiddler="'+this.assignmentTiddler+'"]').click();
jQuery('#pageOneWrapper').scrollTop(this.scroll);
}
Authortool.prototype.editModelsolution = function(){
var tool = this;
if(store.getTiddler(tool.tiddlerName).fields.modelsolutionto ===""){
tool.assignmentTiddler = tool.modelSolution.place.parents('[tiddler]').eq(1).attr('tiddler');
tool.scroll = jQuery('#pageOneWrapper').scrollTop()+tool.modelSolution.place.height();
alert(EbookDictionary.localize('modelsolution removed'));
tool.callFifo = [];
tool.callFifo.push('removeLock');
tool.callFifo.push('removeLockType');
tool.callFifo.push('removeworkingDialog');
tool.callFifo.push('openAccordian');
tool.callNext();
return false;
}
config.options.chkAutoSave = false;
if(tool.modelSolution.editable === false){
tool.modelSolution.initElements();
tool.modelSolution.editable = true;
tool.modelSolution.editElements();
tool.modelSolution.show();
}else{
/************************************
* Modelsolution cancel button click *
*************************************/
tool.modelSolution.place.unbind('elementset-cancel').bind('elementset-cancel',function(){
tool.workingDialog(EbookDictionary.localize('saving'));
delete tool.modelSolution;
if(store.tiddlerExists('creatingModelsolution')){
var autos = config.options.chkAutoSave;
config.options.chkAutoSave = false;
store.deleteTiddler('creatingModelsolution');
config.options.chkAutoSave = autos;
}else{
store.getTiddler(tool.tiddlerName).set(null,tool.oldContent);
}
saveChanges();
tool.callFifo = [];
tool.callFifo.push('removeLock');
tool.callFifo.push('removeLockType');
tool.callFifo.push('removeworkingDialog');
tool.callNext();
});
/************************************
* Modelsolution save button click *
*************************************/
tool.modelSolution.place.unbind('elementset-save').bind('elementset-save',function(){
tool.workingDialog(EbookDictionary.localize('saving'));
var solution = tool.modelSolution;
var savedTiddler = store.getTiddler(solution.tiddlerName);
savedTiddler.fields.elementlanguage=tool.modelSolution.place.find('.landChoise input:checked').val();
solution.editable = false;
solution.save();
if(solution.tiddlerName == 'creatingModelsolution'){
var newmodelsolution = store.createTiddler(tool.findFreeTiddler('modelsolution'));
newmodelsolution.set(newmodelsolution.title,
savedTiddler.text,
savedTiddler.modifier,
savedTiddler.modified,
savedTiddler.tags,
savedTiddler.created,
savedTiddler.fields,
savedTiddler.creator);
tool.sendFifo.push({"title": newmodelsolution.title,"system":3});
var autos = config.options.chkAutoSave;
config.options.chkAutoSave = false;
store.deleteTiddler('creatingModelsolution');
config.options.chkAutoSave = autos;
}else{
savedTiddler.set(savedTiddler.title);
tool.sendFifo.push({"title": savedTiddler.title, "newTiddler": 0,"system":3});
}
saveChanges();
tool.callNext();
});
/************************************
* Modelsolution language *
*************************************/
var langinuse = store.tiddlerExists(tool.tiddlerName) && store.getTiddler(tool.tiddlerName).fields.elementlanguage ?store.getTiddler(tool.tiddlerName).fields.elementlanguage :EbookPages[0].currentlang;
var langselect = tool.modelSolution.place.prepend('<div class="landChoise">'+EbookDictionary.localize('select language')+'</div>').find('.landChoise');
var availableLangs = EbookPages[0].ebook.getLangs();
for(var i=0;i<availableLangs.length;i++){
langselect.append('<span><input name="landChoise" '+(langinuse===availableLangs[i]?'checked="checked" ':'')+'type="radio" value="'+availableLangs[i]+'" id="modelLanguage_'+availableLangs[i]+'"/><label for="modelLanguage_'+availableLangs[i]+'">'+availableLangs[i]+'</label></span>');
}
/************************************
* Modelsolution element remove *
*************************************/
tool.modelSolution.place.find('.solutionanswer .solutionanswerbox').mathquill('textbox').mathquill('latex', tool.modelSolution.modelsolutionAnswer).blur()
.focusout(function(){
tool.modelSolution.modelsolutionAnswer = jQuery(this).mathquill('latex');
tool.modelSolution.save();
});
var edata = {"tiddler": tool.modelSolution.tiddlerName};
tool.modelSolution.place.find('.modelsolutionset:last .ebelement').append('<div class="removesolelem"><a href="javascript:;">X</a></div>');
tool.modelSolution.place.find('.modelsolutionset:last .ebelement .removesolelem a').click(edata, function(){
var index = tool.modelSolution.place.find('.modelsolutionset:last .ebelement').index(jQuery(this).parents('.ebelement'));
if (confirm(EbookDictionary.localize('areyousure'))){
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tool.modelSolution.removeElement(index);
config.options.chkAutoSave = autosaveStatus;
tool.modelSolution.focusFirts=true;
tool.modelSolution.show();
}
});
tool.modelSolution.place.find('.solutionanswer').before(tool.modelSolution.getModelsolutionsToolbar());
}
}
Authortool.prototype.tocedit = function(bookid){
var tool = this;
this.lockType = 'ebooktoc';
if (store.tiddlerExists(bookid + '_toc')){
var toc = DataTiddler.getData(bookid + "_toc", "booktoc", {bookid: bookid, title: "", alttitles: {}, curriculum: "", lang: "", altlangs: [], updateURL: "", style: ""});
} else {
var booktocs = DataTiddler.getData(Emathbook.config.datatiddler, "booktocs", {});
var toc = booktocs[bookid];
}
if (typeof(book) == 'undefined'){
book = {};
}
var book = new Emathbook();
book.init(toc);
this.openDialog('tocedit', 'Edit the table of contents', ['langselect','booknamearea','toclist']); //Localization!!
jQuery('#authordialog_tocedit .langselect').append('<input type="radio" name="translang" value="'+book.defaultlang+'" id="trlang_'+book.defaultlang+'" checked="checked"><label for="trlang_'+book.defaultlang+'">'+book.defaultlang+'</label>');
for (var i = 0; i<book.altlangs.length; i++){
jQuery('#authordialog_tocedit .langselect').append('<input type="radio" name="translang" value="'+book.altlangs[i]+'" id="trlang_'+book.altlangs[i]+'"><label for="trlang_'+book.altlangs[i]+'">'+book.altlangs[i]+'</label>');
}
jQuery('#authordialog_tocedit .langselect input[name="translang"]').click(function(){
tool.newlang = jQuery(this).val();
filltable();
});
tool.newlang = book.defaultlang;
jQuery('#authordialog_tocedit .booknamearea').append('<h2>Book name</h2><dl><dt>Original name:</dt><dd><span class="originaltitle">'+book.title+'</span></dd><dt>New or translated name:</dt><dd><input type="text" class="nametext" value="'+book.title+'" /></dd></dl>');
jQuery('#authordialog_tocedit .booknamearea input.nametext').change(function(){
if (tool.newlang == book.defaultlang){
book.title = jQuery(this).val();
} else {
book.alttitles[tool.newlang] = jQuery(this).val();
}
});
jQuery('#authordialog_tocedit .toclist').append('<h2>Table of contents</h2><table class="translatetable"><thead><tr><th>id</th><th>#</th><th class="transorig">Original</th><th class="trannew">New</th></tr></thead><tbody></tbody></table>');
var filltable = function(){
var titleinput = jQuery('#authordialog_tocedit .booknamearea input.nametext');
var titlename = book.alttitles[tool.newlang] || book.title;
titleinput.val(titlename);
jQuery('#authordialog_tocedit .booknamearea span.originaltitle').empty().append(book.title);
var tbody = jQuery('#authordialog_tocedit .toclist table.translatetable tbody');
tbody.empty();
for (var i = 0; i<book.chapters.length; i++){
var number = book.getNumberedTitle(book.chapters[i]).match(/^(?:[0-9]+\.)*[0-9]+/) || '';
var title = book.getTitle(book.chapters[i]);
var alttitle = book.getTitle(book.chapters[i],tool.newlang);
tbody.append('<tr><td>'+book.chapters[i]+'</td><td>'+number+'</td><td>'+title+'</td><td><input class="transtext" type="text" value="'+alttitle+'" chapid="'+book.chapters[i]+'" /></td></tr>');
}
jQuery('#authordialog_tocedit .toclist table.translatetable tbody input.transtext').focusout(function(){
var chapid = jQuery(this).attr('chapid');
var newtext = jQuery(this).val();
if (!book.tocdict[chapid].alttitles){
book.tocdict[chapid].alttitles = {};
}
if (tool.newlang != book.defaultlang){
book.tocdict[chapid].alttitles[tool.newlang] = newtext;
} else {
book.tocdict[chapid].title = newtext;
}
});
}
filltable();
// Järjestelytyökalu kommentoitu pois.
// jQuery('#authordialog_tocedit .toclist').append(book.tocHtml(false,'front'));
// jQuery('#authordialog_tocedit .toclist ol.ebooktocsubchap li')
// .not('ol li ol li ol li')
// .each(function(){
// if (jQuery(this).find('ol').length == 0){
// jQuery(this).append('<ol class="ebooktocsubchap" style="min-height: 5px; min-width: 5px;"></ol>\n');
// }
// });
// jQuery('#authordialog_tocedit .toclist ol.ebooktocsubchap').sortable({
// placeholder: 'ui-state-highlight',
// helper: 'clone',
// forcePlaceholderSize: true
// }).disableSelection();
// jQuery('#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap').sortable(
// 'option', 'connectWith', '#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap'
// );
// jQuery('#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap > li > ol.ebooktocsubchap').sortable(
// 'option', 'connectWith', '#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap > li > ol.ebooktocsubchap'
// );
alert('Make sure to select the correct language, when translating!');
this.save = function(){
DataTiddler.setData(bookid + '_toc', 'booktoc', book.tocObject());
autoSaveChanges();
this.sendFifo.push({"title": bookid + '_toc', "newTiddler": 0});
this.callNext();
return true;
}
}
Authortool.prototype.editDict = function(){
/******************************************************
* Tool for editing of localization strings in EbookDictionary
******************************************************/
// Define some useful functions.
this.editSelected = function(){
var dicteditor = this;
this.dicttermlist.empty();
var termlist = [];
var currentdict = this.dicts[this.selecteddict];
for (var term in currentdict) {
termlist.push([term, currentdict[term][this.fromlang] || "<i>{{"+term+"}}</i>"]);
}
termlist.sort(function(a,b){
return (a[1] < b[1] ? -1 : 1);
});
for (var i = 0; i < termlist.length; i++) {
var term = termlist[i][0];
var classes = [];
var tranexists = !!currentdict[term][this.tolang];
if (!tranexists) {
classes.push('dict-missing-translation');
}
this.dicttermlist.append('<li term="'+term+'" class="'+classes.join(' ')+'"><a href="javascript:;">'+termlist[i][1]+'</a></li>');
}
this.dicttermlist.find('li a').click(function(e){
e.preventDefault();
dicteditor.dicttermlist.find('li').removeClass('dicttermselected');
var selected = jQuery(this).parent();
dicteditor.selectedterm = selected.attr('term');
selected.addClass('dicttermselected');
dicteditor.editSelectedTerm();
});
this.dicttermtranslate.empty();
}
this.editSelectedTerm = function(){
var dicteditor = this;
this.dicttermtranslate.empty();
var termdata = this.dicts[this.selecteddict][this.selectedterm];
for (var i = 0; i < this.langs.length; i++) {
this.dicttermtranslate.append('<tr><td class="dictlanglabel">'+this.langs[i]+':</td><td><input type="text" value="'+(termdata[this.langs[i]] || '')+'" dictlang="'+this.langs[i]+'" dictempty="'+(!termdata[this.langs[i]])+'" /></td></tr>');
}
this.dicttermtranslate.find('input[dictlang="'+this.tolang+'"]').focus();
this.dicttermtranslate.find('input[type="text"]').bind('focusout.dictchanged', function(e){
var input = jQuery(this);
var currentlang = input.attr('dictlang');
if (input.val() !== termdata[currentlang]) {
dicteditor.editedDicts[dicteditor.selecteddict] = true;
dicteditor.changed = true;
dicteditor.dicts[dicteditor.selecteddict][dicteditor.selectedterm][currentlang] = input.val();
if (currentlang === dicteditor.tolang) {
dicteditor.dicttermlist.find('li[term="'+dicteditor.selectedterm+'"]').removeClass('dict-missing-translation');
}
}
if (input.val()) {
input.attr('dictempty','false');
} else {
input.attr('dictempty','true');
if (currentlang === dicteditor.tolang) {
dicteditor.dicttermlist.find('li[term="'+dicteditor.selectedterm+'"]').addClass('dict-missing-translation');
}
}
});
}
this.strings = {
style: [
'#dicteditor {position: relative; padding: 1em;}',
'#dicteditorselections {left:0; right:0; top:0; position: absolute; margin: 0.5em; overflow: hidden;}',
'#dictarea {position: absolute; top:5em; right:0; bottom:0;left:0;}',
'ul#dicttermlist {position: absolute; top:0; left: 0; bottom: 0; width: 45%; overflow: auto; list-style: none; padding:0; border: 1px solid #666; background-color: white;}',
'ul#dicttermlist li {margin: 0; padding:0; padding-left: 1.3em; border-top: 1px solid white; border-bottom: 1px solid #ddd;}',
'ul#dicttermlist li.dict-missing-translation {font-weight: bold; background-color: #ffeeee;}',
'ul#dicttermlist li.dict-missing-translation:before {display: block; float: left; margin: 0.1em 0.1em 0 -1.2em; content: "!"; border-radius: 50%; background-color: red; text-align: center; width: 1.2em; color: white;}',
'ul#dicttermlist li a {margin: 0; padding:0.2em 0.3em; display: block;}',
'ul#dicttermlist.dictfiltered li {display: none;}',
'ul#dicttermlist.dictfiltered li.dict-missing-translation {display: block;}',
'ul#dicttermlist li.dicttermselected {background-color: #ffffc0;}',
'#dicttermtranslate {position: absolute; top:0; right: 0; bottom: 0; width: 45%; overflow: auto; border: 1px solid #666; padding: 0.5em;}',
'#dicttermtranslate table {width: 100%;}',
'#dicttermtranslate .dictlanglabel {font-weight: bold;}',
'#dicttermtranslate input {display: block; width: 100%; margin: 0.1em 0; border-radius: 0.2em; border: 1px solid #666;}',
'#dicttermtranslate input[dictempty="true"] {background-color: #ffdddd;}'
].join('\n')
}
// Put style-tag in its place if it's not there already or update it.
if (jQuery('head style#emathdicteditorstyle').length == 0){
jQuery('head').append('<style id="emathdicteditorstyle" type="text/css">'+this.strings['style']+'</style>');
} else {
jQuery('head style#emathdicteditorstyle').html(this.strings['style']);
}
var dicteditor = this;
this.dicts = {};
this.dictlist = [];
this.langs = ["en","fi"]
this.fromlang = 'en';
this.tolang = EbookPages[0].currentlang || config.options.txtLang || 'en';
this.selecteddict = 'system';
this.changed = false;
this.editedDicts = {};
var dictsets = store.getTaggedTiddlers('ebdictset');
for (var i = 0; i < dictsets.length; i++) {
var dictname = dictsets[i].data('dictname', '');
if (dictname) {
if (dictname === 'system') {
this.langs = dictsets[i].data('langs', ["en","fi","sv","et"]);
}
this.dictlist.push(dictname);
this.editedDicts[dictname] = false;
this.dicts[dictname] = jQuery.extend(true, {}, DataTiddler.getData(dictsets[i].title, 'ebdict', {}));
}
}
jQuery('#dicteditor').remove();
this.openDialog('dicteditor', EbookDictionary.localize('localization'),[]);
this.dicteditor = this.dialogbox;
this.dicteditor.append('<div id="dicteditorselections"><div id="dictselector">'+EbookDictionary.localize('select dictionary')+': <span class="radio"></span></div><div id="dictlangselector"><label for="dictfilter">'+EbookDictionary.localize('filter unlocalized')+'</label><input id="dictfilter" type="checkbox" /></div></div><div id="dictarea"><ul id="dicttermlist"></ul><div id="dicttermtranslate"><table><tbody></tbody></table></div></div>');
this.dictselector = this.dicteditor.find('#dictselector .radio');
this.dictlangsel = this.dicteditor.find('#dictlangselector');
this.dictarea = this.dicteditor.find('#dictarea');
this.dicttermlist = this.dictarea.find('#dicttermlist');
this.dicttermtranslate = this.dictarea.find('#dicttermtranslate tbody');
var selopts = [];
for (var i = 0; i < this.dictlist.length; i++) {
selopts.push('<input type="radio" name="radio" id="radio_'+this.dictlist[i]+'" dictname="'+this.dictlist[i]+'" '+(this.dictlist[i] === 'system' ? 'checked="checked"' : '')+' /><label for="radio_'+this.dictlist[i]+'">'+this.dictlist[i]+'</label>');
}
this.dictselector.html(selopts.join('\n')).buttonset();
var fromlangs = ['<div style="float:left;"><span>'+EbookDictionary.localize('from lang')+'</span><select id="dictfromlangsel">'];
for (var i = 0; i < this.langs.length; i++) {
fromlangs.push('<option value="'+this.langs[i]+'">'+this.langs[i]+'</option>');
}
fromlangs.push('</select></div>');
this.dictlangsel.append(fromlangs.join('\n'));
var fromlangs = ['<div style="float:right;"><span>'+EbookDictionary.localize('to lang')+'</span><select id="dicttolangsel">'];
for (var i = 0; i < this.langs.length; i++) {
fromlangs.push('<option value="'+this.langs[i]+'" '+(this.langs[i] === this.tolang ? 'selected="selected"' : '')+'>'+this.langs[i]+'</option>');
}
fromlangs.push('</select></div>');
this.dictlangsel.append(fromlangs.join('\n'));
this.dictselector.find('input[type="radio"]').bind('change', function(e){
if (jQuery(this).is(':checked')) {
dicteditor.selecteddict = jQuery(this).attr('dictname');
}
dicteditor.editSelected();
});
this.dictlangsel.find('#dictfilter').bind('change', function(e){
if (jQuery(this).is(':checked')) {
dicteditor.dicttermlist.addClass('dictfiltered');
} else {
dicteditor.dicttermlist.removeClass('dictfiltered');
}
});
this.dictlangsel.find('#dictfromlangsel').bind('change', function(e){
dicteditor.fromlang = jQuery(this).val();
dicteditor.editSelected();
});
this.dictlangsel.find('#dicttolangsel').bind('change', function(e){
dicteditor.tolang = jQuery(this).val();
dicteditor.editSelected();
});
if( jQuery('body').hasClass('adminmode')){
jQuery('#dictselector').append('<span id="addNewkey">'+EbookDictionary.localize('add new key')+'<input id="addKeyinput" type="text"><button>'+EbookDictionary.localize('add')+'</button></span>').find('#addNewkey button').click(function(){
if(jQuery('#addKeyinput').val() && !dicteditor.dicts[dicteditor.selecteddict][jQuery('#addKeyinput').val()] ){
dicteditor.dicts[dicteditor.selecteddict][jQuery('#addKeyinput').val()]={};
dicteditor.editedDicts[dicteditor.selecteddict] = true;
dicteditor.changed = true;
jQuery('#addKeyinput').val("");
dicteditor.editSelected();
}else{
if(jQuery('#addKeyinput').val()){
alert(EbookDictionary.localize('key already exists'));
jQuery('#addKeyinput').val("");
}
}
});
}
this.editSelected();
this.save = function(){
for (var i = 0; i < dictsets.length; i++) {
var currenttiddler = dictsets[i].title;
var currentdict = DataTiddler.getData(currenttiddler, 'dictname', '');
if (this.editedDicts[currentdict] && store.tiddlerExists(currenttiddler)) {
DataTiddler.setData(currenttiddler, 'ebdict', this.dicts[currentdict], {});
this.sendFifo.push({"title": currenttiddler, "system": 2});
}
}
autoSaveChanges();
if (this.changed) {
EbookDictionary.init();
}
this.callNext();
return true;
}
}
Authortool.prototype.editElement = function(){
/******************************************************
* Tool for edit element in chapter/section/subsection
******************************************************/
var tool = this;
var editorviews = jQuery();
var geoeditorviews = jQuery();
var ebookimages = jQuery();
var signchartviews = jQuery();
var translateElements = jQuery();
var translateImages = jQuery();
var translateSubs = jQuery();
var translatesdAssignments = jQuery();
var translatesetofOtherassignments = jQuery();
var translateOtherassignments = jQuery();
var subelements = jQuery();
this.assignmentlist = (jQuery('#pageOne').find('.sdbookassignmentlist').length != 0);
if (!this.assignmentlist){
editorviews = jQuery('#pageOne .qededitor,#pageTwoWrapper .extraboxcontent:not(.nottranslated) .qededitor');
signchartviews = jQuery('#pageOne .pssc_rendered');
ebookimages = jQuery('#pageOne .ebookimage');
geoeditorviews = jQuery('#pageOne .grapheditor');
subelements = jQuery('#pageOne .extraboxicon');
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
translateElements = [];
translateImages = [];
translateSubs = [];//notTranslatedextra
for(var i=ebookimages.length-1;i >= 0;i--){
if(ebookimages.eq(i).parent('.notTranslatedimage').length > 0){
translateImages.push(ebookimages.eq(i)[0]);
ebookimages.splice(i,1);
}
}
for(var i=subelements.length-1;i >= 0;i--){
if(subelements.eq(i).parent('.notTranslatedextra').length > 0){
translateSubs.push(subelements.eq(i)[0]);
subelements.splice(i,1);
}
}
for(var i=pageElements.length-1;i >= 0;i--){
if(store.getTiddler(pageElements.eq(i).attr('tiddler')).isTagged('ebookgraph_image')){
pageElements.splice(i,1);
}else if(pageElements.eq(i).find('.notTranslated').length > 0){
translateElements.push(pageElements.eq(i)[0]);
}
}
translateSubs = jQuery(translateSubs);
translateImages = jQuery(translateImages);
translateElements = jQuery(translateElements);
var elementType = '[tiddler]';
}else{
var accordions = jQuery('#pageOne .sdbookassignmentlist .assignmentAccordion0,#pageOne .sdbookassignmentlist .otherassignmentAccordion');
accordions.accordion( "option", "animated", false );
accordions.find('h3').click();
accordions.find('h3.ui-state-active').click();
var sdAssignments = jQuery('#pageOne .sdbookassignmentlist .assignmentAccordion0 h3');
var setofOtherassignments = jQuery('#pageOne .sdbookassignmentlist .otherassignmentAccordion h3');
var Otherassignments = jQuery('#pageOne .sdbookassignmentlist .otherassignmentAccordion li span[tiddler],#pageOne .sdbookassignmentlist .otherassignmentAccordion .emathQuizassignment[tiddler]');
geoeditorviews = jQuery('#pageOne .grapheditor');
if(Emathbook.options && Emathbook.options.pages[0]["lang"] != Emathbook.options.pages[0]["defaultlang"]){
translatesdAssignments = [];
translatesetofOtherassignments = [];
translateOtherassignments = [];
var notTranslatedgeoeditors = jQuery('#pageOne .notTranslated .grapheditor');
geoeditorviews = geoeditorviews.not(notTranslatedgeoeditors);
for(var i=sdAssignments.length-1;i >= 0;i--){
if(sdAssignments.eq(i).next().find('.question_text').parent('.notTranslated').length > 0){
translatesdAssignments.push(sdAssignments.eq(i)[0]);
sdAssignments.splice(i,1);
}
}
for(var i=setofOtherassignments.length-1;i >= 0;i--){
if(setofOtherassignments.eq(i).hasClass('notTranslated')){
translatesetofOtherassignments.push(setofOtherassignments.eq(i)[0]);
setofOtherassignments.splice(i,1);
}
}
for(var i=Otherassignments.length-1;i >= 0;i--){
if(Otherassignments.eq(i).parents('.question_text').parent('.notTranslated').length > 0){
translateOtherassignments.push(Otherassignments.eq(i)[0]);
Otherassignments.splice(i,1);
}
}
translatesdAssignments = jQuery(translatesdAssignments);
translatesetofOtherassignments = jQuery(translatesetofOtherassignments);
translateOtherassignments = jQuery(translateOtherassignments);
}
var pageElements = sdAssignments.add(setofOtherassignments).add(Otherassignments);
var elementType = 'h3';
}
if (pageElements.length == 0 && translatesdAssignments.add(translatesetofOtherassignments).add(translateOtherassignments).add(translateImages).add(translateSubs).add(translateElements).length == 0 ){
alert('Nothing to edit.'); //Localization
tool.callFifo = [];
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
return false;
}
/*******
Translate sknippulat SD assignment elementeille
******/
//Localization!! sknippulat
translatesdAssignments.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var dataTiddler = store.getTiddler(tool.tiddlerName);
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
tool.openDialog('translatecontent', 'Translate selected content', ['ebooktitle','level','elem_content','solutionAnswer', 'tag_insert']);
tool.dialogbox.find('.ebooktitle').append('<p class="translatealert">'+translatealert+'</p><h2>Additional title:</h2><input class="ebooktitleInput" type="text" value="'+(typeof(dataTiddler.fields.ebooktitle) !='undefined'? dataTiddler.fields.ebooktitle : '')+'"/>');
tool.dialogbox.find('.level').append('<form><div class="assigment_level_changer"><input type="radio" id="level0" name="level" value=0 /><label for="level0">*</label> <input type="radio" id="level1" value=1 name="level" /><label for="level1">**</label> <input type="radio" id="level2" value=2 name="level" /><label for="level2">***</label></div></form>').find('.assigment_level_changer').buttonset();
tool.dialogbox.find('.level .assigment_level_changer #level'+DataTiddler.getData(dataTiddler.title,'level',0)).click().change();
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</textarea>');
tool.dialogbox.find('.solutionAnswer').append('<div class="assignmentSolution solutionText"><span class="mathquill-textbox">'+DataTiddler.getData(dataTiddler.title,'assignmentSolution','')+'</span></div>').find('.assignmentSolution .mathquill-textbox').mathquill('textbox');
tool.save = function(){
var assignmentData = jQuery.extend(true, {},DataTiddler.getDataObject(dataTiddler.title));
assignmentData.level = this.dialogbox.find('.level .assigment_level_changer input:checked').val();
assignmentData.assignmentSolution = this.dialogbox.find('.assignmentSolution .mathquill-textbox').mathquill('latex');
var content = this.dialogbox.find('.elem_content textarea').val();
var translatedTiddlername = tool.tiddlerName+'_'+translang;
var translatedTiddler = store.createTiddler(translatedTiddlername);
this.saveTiddler(translatedTiddlername, content+'<data>'+JSON.stringify(assignmentData)+'</data>', dataTiddler.tags,this.dialogbox.find('input.ebooktitleInput').val(),null,{"translation":tool.tiddlerName});
this.sendFifo.push({"title": translatedTiddlername, "newTiddler": 1});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
/*******
Translate sknippulat perustehtävä setille
******/
//Localization!! sknippulat
translatesetofOtherassignments.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var dataTiddler = store.getTiddler(tool.tiddlerName);
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var rex = new RegExp(/(?:^#.*<<showAssignment.*\n)+/m);
var assignmentblock = (dataTiddler.text.match(rex)?dataTiddler.text.match(rex)[0]:"");
var contentblocks = dataTiddler.text.split(rex);
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
tool.openDialog('translatecontent', 'Translate selected content', ['ebooktitle','pre_elem_content','assignment_block','post_elem_content', 'tag_insert']);
tool.dialogbox.find('.ebooktitle').append('<p class="translatealert">'+translatealert+'</p><h2>Additional title:</h2><input class="ebooktitleInput" type="text" value="'+(typeof(dataTiddler.fields.ebooktitle) !='undefined'? dataTiddler.fields.ebooktitle : '')+'"/>');
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.pre_elem_content').append('<h2>Text content:</h2><textarea class="pre_elem_textarea">'+contentblocks[0]+'</textarea>');
wikify( assignmentblock ,tool.dialogbox.find('.assignment_block')[0]);
tool.dialogbox.find('.post_elem_content').append('<h2>Text content:</h2><textarea class="post_elem_textarea">'+(assignmentblock?contentblocks[1]:"")+'</textarea>');
tool.save = function(){
var content = this.dialogbox.find('.pre_elem_content textarea').val()+assignmentblock+this.dialogbox.find('.post_elem_content textarea').val();
var translatedTiddlername = tool.tiddlerName+'_'+translang;
var translatedTiddler = store.createTiddler(translatedTiddlername);
this.saveTiddler(translatedTiddlername, content, dataTiddler.tags, this.dialogbox.find('input.ebooktitleInput').val(),null,{"translation":tool.tiddlerName});
this.sendFifo.push({"title": translatedTiddlername, "newTiddler": 1});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
/*******
Translate sknippulat yhdelle perustehtävälle
******/
//Localization!! sknippulat
translateOtherassignments.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var dataTiddler = store.getTiddler(tool.tiddlerName);
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
tool.assignmentData = DataTiddler.getDataObject(dataTiddler.title);
tool.openDialog('translatecontent', 'Translate selected content', ['translatefrom','elem_content']);
tool.dialogbox.find('.translatefrom').append('<p class="translatealert">'+translatealert+'</p>');
switch(tool.assignmentData.assignmentType){
case "1":
tool.dialogbox.find('.elem_content').append('<h2>Question text:</h2><span class="question_text">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</span>').find('.question_text').mathquill('textbox');
break;
case "2":
tool.dialogbox.find('.elem_content').append('<li class="subquestion" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable">'+tool.assignmentData['correct'].replace('\\(','$').replace('\\)','$')+'</span></li></ul>');
for(var i=0;i<tool.assignmentData['wrong'].length;i++){
tool.dialogbox.find('.elem_content ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable">'+tool.assignmentData['wrong'][i].replace('\\(','$').replace('\\)','$')+'</span></li>');
}
tool.dialogbox.find('.elem_content').append('<hr>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end();
break;
case "3":
var shortText = dataTiddler.text.replace(/<data>.*<\/data>/,'');
for(var i=0;i<(tool.assignmentData['correct'] ? tool.assignmentData['correct'].length : 0);i++){
shortText = shortText.replace('\\editable{}',tool.assignmentData['correct'][i]);
}
tool.dialogbox.find('.elem_content').append('<h2>Original text:</h2><span class="original_text">'+wikifyStatic(shortText)+'</span><h2>Question text:</h2><span class="question_text">'+shortText+'</span>').find('.question_text').mathquill('textbox');
break;
case "5":
var orderSd = tool.dialogbox.find('.elem_content').append('<div class="orderSdTrans"></div>').find('.orderSdTrans');
wikify(dataTiddler.text,orderSd[0],null,dataTiddler);
tool.oldcontent = dataTiddler.text;
tool.dialogbox.find('.qededitorbuttons a.command_qededit').click();
tool.cancel = function(){
dataTiddler.set(null, tool.oldcontent);
autoSaveChanges();
};
break;
case "7":
var fillTableText = dataTiddler.text.replace(/<data>.*<\/data>/,'');
/*
for(var i=0;i<(tool.assignmentData['correct'] ? tool.assignmentData['correct'].length : 0);i++){
shortText = shortText.replace('\\editable{}',tool.assignmentData['correct'][i]);
}*/
var correctNro = -1;
var dialogtableData = tool.assignmentData['table'][fillTableText.match(/<<ebooktable\ ([^\ ]*)\ [^>]*>>/)[1]];
var dialogfillTable = tool.dialogbox.find('.elem_content').append('<h2>Edit Filltable:</h2><span class="question_text" style="display:none;">'+fillTableText+'</span><table id="tranlateFilltable" class="'+dialogtableData['class']+'"><tbody></tbody></table>').find('tbody');
for(var tableRows = 0; tableRows < dialogtableData['rows'];tableRows++){
var thisrow = dialogfillTable.append('<tr class="'+((tableRows+1)%2===1?'evenRow':'oddRow')+'"></tr>').find('tr').last();
for(var tableCols = 0; tableCols < dialogtableData['cols'];tableCols++){
var thiscolsNro = (tableRows*dialogtableData['cols']+tableCols);
var doReplace=false;
var tdContent = dialogtableData.data[tableRows][tableCols];
while(tdContent.indexOf('\\editable{}') !== -1 && correctNro <tool.assignmentData['correct'].length){
doReplace=true;
correctNro++;
tdContent = tdContent.replace('\\editable{}',tool.assignmentData['correct'][correctNro]);
}
thisrow.append('<td><span id="shellText'+thiscolsNro+'">'+tdContent+'</span></td>').find('td #shellText'+thiscolsNro).mathquill((dialogtableData.types[tableRows][tableCols]==="math"?'editable':'textbox'));
}
}
break;
default:
alert('Doesn\'t work (yet). Sorry.');
tool.dialogbox.dialog("destroy").remove();
tool.callFifo = [];
tool.removeLock();
break;
}
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
var translatedTiddlername = tool.tiddlerName+'_'+translang;
var translatedTiddler = store.createTiddler(translatedTiddlername);
switch(tool.assignmentData.assignmentType){
case "1":
this.saveTiddler(translatedTiddlername, tool.dialogbox.find('.elem_content .question_text').mathquill('latex')+'<data>'+JSON.stringify(tool.assignmentData)+'</data>', dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
break;
case "2":
tool.assignmentData['correct'] = tool.dialogbox.find('.elem_content span.correctchoice').mathquill('latex');
var wrongs = [];
var wrongelems=tool.dialogbox.find('.elem_content span.incorrectchoise');
for ( var i=0;i<wrongelems.length;i++){wrongs.push(wrongelems.eq(i).mathquill('latex'));}
tool.assignmentData['wrong'] = wrongs;
this.saveTiddler(translatedTiddlername, tool.dialogbox.find('.elem_content .questionMulti').mathquill('latex')+'<data>'+JSON.stringify(tool.assignmentData)+'</data>', dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
break;
case "3":
var SAquestion = tool.dialogbox.find('.elem_content .question_text').mathquill('latex');
var solutionsSpans= tool.dialogbox.find('.elem_content .question_text').find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var SAsolution = solutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
if (hasSolutions){tool.assignmentData["correct"] =SAsolutions;}else{delete tool.assignmentData["correct"];}
this.saveTiddler(translatedTiddlername, SAquestion+'<data>'+JSON.stringify(tool.assignmentData)+'</data>',dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
break;
case "5":
this.saveTiddler(translatedTiddlername, dataTiddler.text,dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
dataTiddler.set(null,tool.oldcontent);
break;
case "7":
var fillTableMacro = "<<ebooktable assignmentTable0 "+tool.dialogbox.find('table#tranlateFilltable').attr('class')+" savehere>>";
var correctSolutions =[];
var fillTableRowCount = tool.dialogbox.find('table#tranlateFilltable tr').length;
var fillTableCols = tool.dialogbox.find('table#tranlateFilltable td');
var fillTableColCount = fillTableCols.length/fillTableRowCount;
var assignmentTable = {};
assignmentTable['rows'] = fillTableRowCount;
assignmentTable['cols'] = fillTableColCount;
assignmentTable['class'] = tool.dialogbox.find('table#tranlateFilltable').attr('class');
assignmentTable['caption'] = "";
assignmentTable['types'] = [];
assignmentTable['data'] = [];
var assignmentData = {};
assignmentData['table'] = {};
assignmentData['assignmentType'] = "7";
var colData=[];
var colTypes=[];
var hasSolutions = true;
for(var tdElems = 0; tdElems < fillTableCols.length; tdElems++){
if( tdElems !== 0 && tdElems%fillTableColCount ===0){
assignmentTable['data'].push(colData);
assignmentTable['types'].push(colTypes);
colData=[];
colTypes=[];
}
var tdMathquillContent = fillTableCols.eq(tdElems).children('span');
if(tdMathquillContent.hasClass('mathquill-textbox')){
colTypes.push("text");
}else{
colTypes.push("math");
}
var tdContent = tdMathquillContent.mathquill('latex');
var solutionIncontent = tdMathquillContent.find('.solution');
for(var j=0; j<solutionIncontent.length;j++){
var fillTableSolution = solutionIncontent.eq(j).mathquill('latex');
fillTableSolution = (fillTableSolution.charAt(fillTableSolution.length-1)==" "? fillTableSolution.substring(0,fillTableSolution.length-1): fillTableSolution);
fillTableSolution = fillTableSolution.replace(/\ ([\+\-\}])/g,'$1');
correctSolutions.push(fillTableSolution);
if (fillTableSolution==""){
hasSolutions = false;
}
tdContent = tdContent.replace('\\solution{'+fillTableSolution+'}','\\solution{\\editable{}}');
}
colData.push(tdContent);
}
if(hasSolutions){
assignmentData['correct']=correctSolutions;
}else{
assignmentData['correct']=[];
}
assignmentData['table']['assignmentTable0']=assignmentTable;
if(assignmentData['correct'].length === tool.assignmentData['correct'].length){
this.saveTiddler(translatedTiddlername, fillTableMacro+'<data>'+JSON.stringify(assignmentData)+'</data>',dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",jQuery.pageTiddler(),{"translation":(dataTiddler.fields.translations ? dataTiddler.fields.translations+' '+tool.tiddlerName : tool.tiddlerName)});
}else{
alert('check correct solutions!');
return false;
}
break;
default:
alert('If you see this contact Petri!');
break;
}
this.sendFifo.push({"title": translatedTiddlername, "newTiddler": 1});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
/*******
Translate sknippulat ebookbox elementeille (lähinnä kai)
******/
//Localization!! sknippulat
translateElements.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data');
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
tool.openDialog('translatecontent', 'Translate selected content', ['elem_content', 'tag_insert']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.elem_content').append('<p class="translatealert">'+translatealert+'</p><h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea>');
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
var translatedTiddlername = tool.tiddlerName+'_data_'+Emathbook.options.pages[0]["lang"];
var translatedTiddler = store.createTiddler(translatedTiddlername);
this.saveTiddler(translatedTiddlername, content, dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
this.sendFifo.push({"title": translatedTiddlername, "newTiddler": 1});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
/*******
Edit sknippulat ebookbox elementeille ja tehtäville
******/
pageElements.not(translateElements).append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
//alert(tool.tiddlerName);
if (tool.assignmentlist){
tool.tiddlerName += (Emathbook.options && Emathbook.options.pages[0]["lang"] != Emathbook.options.pages[0]["defaultlang"] && tool.tiddlerName.substr(tool.tiddlerName.length-2) != Emathbook.options.pages[0]["lang"])? "_"+Emathbook.options.pages[0]["lang"] : '';
var dataTiddler = store.getTiddler(tool.tiddlerName);
if(jQuery(this).parents('.otherassignmentAccordion').length > 0){
if( !dataTiddler.isTagged('otherassignment')){
tool.isOtherAssignment = true;
tool.assignmentData = DataTiddler.getDataObject(dataTiddler.title);
tool.openDialog('editassignment', 'Edit selected assignment', ['elem_content','original_content','default_content']);
switch(tool.assignmentData.assignmentType){
case "1":
tool.dialogbox.find('.elem_content').append('<h2>Question text:</h2><span class="question_text">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</span>').find('.question_text').mathquill('textbox');
break;
case "2":
tool.dialogbox.find('.elem_content').append('<li class="subquestion" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable">'+tool.assignmentData['correct'].replace('\\(','$').replace('\\)','$')+'</span></li></ul>');
for(var i=0;i<tool.assignmentData['wrong'].length;i++){
tool.dialogbox.find('.elem_content ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable">'+tool.assignmentData['wrong'][i].replace('\\(','$').replace('\\)','$')+'</span></li>');
}
tool.dialogbox.find('.elem_content').append('<hr><button class="addMultiwrong">Add incorrect</button></li>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end()
.find('.addMultiwrong:last').button().click(function(){
jQuery(this).parent().find('ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li>').find('.mathquill-editable:last').mathquill('textbox');
});
break;
case "3":
var shortText = dataTiddler.text.replace(/<data>.*<\/data>/,'');
for(var i=0;i<(tool.assignmentData['correct'] ? tool.assignmentData['correct'].length : 0);i++){
shortText = shortText.replace('\\editable{}',tool.assignmentData['correct'][i]);
}
tool.dialogbox.find('.elem_content').append('<h2>Question text:</h2><span class="original_text">'+wikifyStatic(shortText)+'</span><h2>Question text:</h2><span class="question_text">'+shortText+'</span>').find('.question_text').mathquill('textbox');
break;
case "7":
var fillTableText = dataTiddler.text.replace(/<data>.*<\/data>/,'');
var correctNro = -1;
var dialogtableData = tool.assignmentData['table'][fillTableText.match(/<<ebooktable\ ([^\ ]*)\ [^>]*>>/)[1]];
var dialogfillTable = tool.dialogbox.find('.elem_content').append('<h2>Edit Filltable:</h2><span class="question_text" style="display:none;">'+fillTableText+'</span><table id="tranlateFilltable" class="'+dialogtableData['class']+'"><tbody></tbody></table>').find('tbody');
for(var tableRows = 0; tableRows < dialogtableData['rows'];tableRows++){
var thisrow = dialogfillTable.append('<tr class="'+((tableRows+1)%2===1?'evenRow':'oddRow')+'"></tr>').find('tr').last();
for(var tableCols = 0; tableCols < dialogtableData['cols'];tableCols++){
var thiscolsNro = (tableRows*dialogtableData['cols']+tableCols);
var doReplace=false;
var tdContent = dialogtableData.data[tableRows][tableCols];
while(tdContent.indexOf('\\editable{}') !== -1 && correctNro <tool.assignmentData['correct'].length){
doReplace=true;
correctNro++;
tdContent = tdContent.replace('\\editable{}',tool.assignmentData['correct'][correctNro]);
}
thisrow.append('<td><span id="shellText'+thiscolsNro+'">'+tdContent+'</span></td>').find('td #shellText'+thiscolsNro).mathquill((dialogtableData.types[tableRows][tableCols]==="math"?'editable':'textbox'));
}
/*
thisrow.append('<td class="removeRow">Remove row</td>').find('.removeRow').click(function(){
if(confirm('This will delete row in table.Are you sure?')){
jQuery(this).parent('tr').remove();
}
});*/
}
//TODO: ADD "buttons" to add/remove cols and rows
break;
case "8":
if(jQuery('body').hasClass('adminmode')){
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea>');
}else{
alert('Admin only. Sorry.');
tool.dialogbox.dialog("destroy").remove();
jQuery('#pageOneNavi').show();
tool.callFifo = [];
tool.removeLock();
}
break;
default:
alert('Ei toimi vielä. Sorry.'+tool.assignmentData.assignmentType);
tool.dialogbox.dialog("destroy").remove();
jQuery('#pageOneNavi').show();
tool.callFifo = [];
tool.removeLock();
break;
}
}else{
tool.otherassignmentContainer = true;
tool.openDialog('editcontent', 'Edit selected content', ['elemTitle','pre_elem_content','assignmentlist','post_elem_content','elemData', 'tag_insert','original_content','default_content']);
var textData = dataTiddler.text.split('<data>');
var otherAssignmenttext = textData[0];
if(textData.length === 1){
var otherAssignmentdata = '{}';
}else{
var otherAssignmentdata = textData[1].replace('</data>','');
}
var postText = "";
var restText = "";
var assignmentlistbegin = -1;
var assignmentlistend = 0;
if(otherAssignmenttext.charAt(0) ==="#"){
var preText = "";
restText = otherAssignmenttext;
assignmentlistbegin = 0;
}else{
if(otherAssignmenttext.indexOf('\n#') !== -1){
var preText = otherAssignmenttext.substr(0, otherAssignmenttext.indexOf('\n#'));
restText = otherAssignmenttext.substr(otherAssignmenttext.indexOf('\n#')+1);
assignmentlistbegin = otherAssignmenttext.indexOf('\n#')+1;
}else{
var preText = otherAssignmenttext;
}
}
while(restText){
if(restText.charAt(restText.indexOf('\n')+1) === "#"){
assignmentlistend += restText.indexOf('\n')+1;
restText = restText.substr(restText.indexOf('\n')+1);
}else{
postText = restText.substr(restText.indexOf('\n')+1);
assignmentlistend += restText.indexOf('\n');
restText = "";
}
}
var assignmentlistText = otherAssignmenttext.substr(assignmentlistbegin,assignmentlistend);
tool.otherassignmentlistAsText = assignmentlistText;
tool.otherassignmentdataAsText = otherAssignmentdata;
tool.dialogbox.find('.elemTitle').append('<h2>Title:</h2><input type="text" class="pre_elem_title" value="'+dataTiddler.fields.ebooktitle+'">');
tool.dialogbox.find('.pre_elem_content').append('<h2>Text content:</h2><textarea class="pre_elem_content">'+preText+'</textarea>');
tool.dialogbox.find('.assignmentlist').append('<h2>Assignmentlist:</h2><div class="elem_data">'+assignmentlistText.replace(/</g,'<').replace(/>/g,'>').replace(/\n/g,'<br/>')+'</div>');
tool.dialogbox.find('.post_elem_content').append('<h2>Text content:</h2><textarea class="post_elem_content">'+postText+'</textarea>');
tool.dialogbox.find('.elemData').append('<h2>DataObject:</h2><textarea class="elemData">'+otherAssignmentdata+'</textarea>');
tool.dialogbox.find('.original_content')
.append('<button class="open_original">Before editing</button><div class="original_text hidden_original">'+dataTiddler.text.replace(/</g,'<').replace(/>/g,'>')+'</div>')
.find('button.open_original').click(function(){
var textBox = jQuery(this).parent().children('.original_text');
if(textBox.hasClass('hidden_original')){
textBox.removeClass('hidden_original');
}else{
textBox.addClass('hidden_original');
}
});
}
}else{
tool.openDialog('editassignment', 'Edit selected assignment', ['ebooktitle','level','elem_content', 'solutionAnswer', 'tag_insert','original_content','default_content']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.ebooktitle').append('<h2>Additional title:</h2><input class="ebooktitleInput" type="text" value="'+(typeof(dataTiddler.fields.ebooktitle) !='undefined'? dataTiddler.fields.ebooktitle : '')+'"/>');
tool.dialogbox.find('.level').append('<form><div class="assigment_level_changer"><input type="radio" id="level0" name="level" value=0 /><label for="level0">*</label> <input type="radio" id="level1" value=1 name="level" /><label for="level1">**</label> <input type="radio" id="level2" value=2 name="level" /><label for="level2">***</label></div></form>').find('.assigment_level_changer').buttonset();
tool.dialogbox.find('.level .assigment_level_changer #level'+DataTiddler.getData(dataTiddler.title,'level',0)).click().change();
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text.replace(/<data>.*<\/data>/,'')+'</textarea>');
tool.dialogbox.find('.solutionAnswer').append('<div class="assignmentSolution solutionText"><span class="mathquill-textbox">'+DataTiddler.getData(dataTiddler.title,'assignmentSolution','')+'</span></div>').find('.assignmentSolution .mathquill-textbox').mathquill('textbox');
}
}else{
if(Emathbook.options.pages[0]["lang"]==Emathbook.options.pages[0]["defaultlang"]){
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data');
}else{
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data_'+Emathbook.options.pages[0]["lang"]);
dataTiddler.fields.translation = tool.tiddlerName+'_data';
}
tool.openDialog('editcontent', 'Edit selected content', ['elem_content', 'tag_insert','original_content','default_content']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea>');
tool.dialogbox.find('.original_content')
.append('<button class="open_original">Before editing</button><div class="original_text hidden_original">'+dataTiddler.text.replace(/</g,'<').replace(/>/g,'>')+'</div>')
.find('button.open_original').click(function(){
var textBox = jQuery(this).parent().children('.original_text');
if(textBox.hasClass('hidden_original')){
textBox.removeClass('hidden_original');
}else{
textBox.addClass('hidden_original');
}
});
if(Emathbook.options.pages[0]["lang"]!=Emathbook.options.pages[0]["defaultlang"]){
tool.dialogbox.find('.default_content')
.append('<button class="open_default">Original ('+Emathbook.options.pages[0]["defaultlang"]+')</button><div class="original_text hidden_default">'+store.getTiddlerText(tool.tiddlerName+'_data').replace(/</g,'<').replace(/>/g,'>')+'</div>')
.find('button.open_default').click(function(){
var textBox = jQuery(this).parent().children('.original_text');
if(textBox.hasClass('hidden_default')){
textBox.removeClass('hidden_default');
}else{
textBox.addClass('hidden_default');
}
});
}
}
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
if (tool.assignmentlist){
if(!tool.otherassignmentContainer){
if(tool.isOtherAssignment){
switch(tool.assignmentData.assignmentType){
case "1":
this.saveTiddler(dataTiddler.title, tool.dialogbox.find('.elem_content .question_text').mathquill('latex')+'<data>'+JSON.stringify(tool.assignmentData)+'</data>', [],'');
break;
case "2":
tool.assignmentData['correct'] = tool.dialogbox.find('.elem_content span.correctchoice').mathquill('latex');
var wrongs = [];
var wrongelems=tool.dialogbox.find('.elem_content span.incorrectchoise');
for ( var i=0;i<wrongelems.length;i++){wrongs.push(wrongelems.eq(i).mathquill('latex'));}
tool.assignmentData['wrong'] = wrongs;
this.saveTiddler(dataTiddler.title, tool.dialogbox.find('.elem_content .questionMulti').mathquill('latex')+'<data>'+JSON.stringify(tool.assignmentData)+'</data>', [],'');
break;
case "3":
var SAquestion = tool.dialogbox.find('.elem_content .question_text').mathquill('latex');
var solutionsSpans= tool.dialogbox.find('.elem_content .question_text').find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var SAsolution = solutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
if (hasSolutions){tool.assignmentData["correct"] =SAsolutions;}else{delete tool.assignmentData["correct"];}
this.saveTiddler(dataTiddler.title, SAquestion+'<data>'+JSON.stringify(tool.assignmentData)+'</data>', [],'');
break;
case "7":
var fillTableMacro = "<<ebooktable assignmentTable0 "+tool.dialogbox.find('table#tranlateFilltable').attr('class')+" savehere>>";
var correctSolutions =[];
var fillTableRowCount = tool.dialogbox.find('table#tranlateFilltable tr').length;
var fillTableCols = tool.dialogbox.find('table#tranlateFilltable td');
var fillTableColCount = fillTableCols.length/fillTableRowCount;
var assignmentTable = {};
assignmentTable['rows'] = fillTableRowCount;
assignmentTable['cols'] = fillTableColCount;
assignmentTable['class'] = tool.dialogbox.find('table#tranlateFilltable').attr('class');
assignmentTable['caption'] = "";
assignmentTable['types'] = [];
assignmentTable['data'] = [];
var assignmentData = {};
assignmentData['table'] = {};
assignmentData['assignmentType'] = "7";
var colData=[];
var colTypes=[];
var hasSolutions = true;
for(var tdElems = 0; tdElems < fillTableCols.length; tdElems++){
if( tdElems !== 0 && tdElems%fillTableColCount ===0){
assignmentTable['data'].push(colData);
assignmentTable['types'].push(colTypes);
colData=[];
colTypes=[];
}
var tdMathquillContent = fillTableCols.eq(tdElems).children('span');
if(tdMathquillContent.hasClass('mathquill-textbox')){
colTypes.push("text");
}else{
colTypes.push("math");
}
var tdContent = tdMathquillContent.mathquill('latex');
var solutionIncontent = tdMathquillContent.find('.solution');
for(var j=0; j<solutionIncontent.length;j++){
var fillTableSolution = solutionIncontent.eq(j).mathquill('latex');
fillTableSolution = (fillTableSolution.charAt(fillTableSolution.length-1)==" "? fillTableSolution.substring(0,fillTableSolution.length-1): fillTableSolution);
fillTableSolution = fillTableSolution.replace(/\ ([\+\-\}])/g,'$1');
correctSolutions.push(fillTableSolution);
if (fillTableSolution==""){
hasSolutions = false;
}
tdContent = tdContent.replace('\\solution{'+fillTableSolution+'}','\\solution{\\editable{}}');
}
colData.push(tdContent);
}
assignmentTable['data'].push(colData);
assignmentTable['types'].push(colTypes);
if(hasSolutions){
assignmentData['correct']=correctSolutions;
}else{
assignmentData['correct']=[];
}
assignmentData['table']['assignmentTable0']=assignmentTable;
this.saveTiddler(dataTiddler.title, fillTableMacro+'<data>'+JSON.stringify(assignmentData)+'</data>',dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",jQuery.pageTiddler(),dataTiddler.fields);
break;
case "8":
this.saveTiddler(dataTiddler.title, content, [],'');
break;
default:
alert('moi');
break;
}
}else{
var assignmentData = DataTiddler.getDataObject(dataTiddler.title);
assignmentData.level = this.dialogbox.find('.level .assigment_level_changer input:checked').val();
assignmentData.assignmentSolution = this.dialogbox.find('.assignmentSolution .mathquill-textbox').mathquill('latex');
this.saveTiddler(dataTiddler.title, content+'<data>'+JSON.stringify(assignmentData)+'</data>', [],this.dialogbox.find('input.ebooktitleInput').val());
}
}else{
try{
JSON.parse(this.dialogbox.find('.elemData textarea.elemData').val());
var newelemData = this.dialogbox.find('.elemData textarea.elemData').val();
}catch(e){
var newelemData = this.otherassignmentdataAsText;
}
this.saveTiddler(dataTiddler.title, this.dialogbox.find('.pre_elem_content textarea.pre_elem_content').val()+"\n"+this.otherassignmentlistAsText+"\n"+this.dialogbox.find('.post_elem_content textarea.post_elem_content').val()+"\n<data>"+newelemData+"</data>", [],this.dialogbox.find('.elemTitle input').val(), null, dataTiddler.fields);
}
}else{
this.saveTiddler(dataTiddler.title, content, [],'', null, dataTiddler.fields);
}
this.sendFifo.push({"title": dataTiddler.title, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
// })});
});
/***************************************************
** Geoditor edit Mode **
***************************************************/
geoeditorviews.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
jQuery(this).parents('.ui-accordion-content').addClass('dontcloseme');
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
tool.geoelement = jQuery(this).parents('.grapheditor').eq(0);
tool.geoelement.css('border-bottom','2px solid red').css('border-left','2px solid red').css('border-right','2px solid red');
tool.tiddlerName=tool.geoelement.parents('[tiddler]').eq(0).attr('tiddler');
var tiddler = store.getTiddler(tool.tiddlerName);
tool.oldcontent = tiddler.text;
tool.cancel = function(){
tiddler.set(null, tool.oldcontent);
autoSaveChanges();
}
tool.sendFifo.push({"title": tool.tiddlerName, "newTiddler": 0});
var options={};
var geoname = tool.geoelement.attr('geoeditor');
var geosize = tool.geoelement.attr('geoeditorsize');
options.editable= true;
var geoeditors = (tool.tiddlerName ?DataTiddler.getData(tool.tiddlerName, 'geoeditors',[]):[]);
var editor = jQuery.extend(true, [], geoeditors[geoname]);
if (editor.length > 0){
options.scenes = editor;
}
tool.geoelement.before('<div class="geoeditorauthorbuttons"><span class="sizeSlect">Size:<select class="imageSize"><option value="tiny">Tiny</option><option value="small">Small</option><option value="medium">Medium</option><option value="large">Large</option><option value="full">Full</option></select> Square<input class="isSquare" type="checkbox" value="isSquare" name="imageSquare"></input> Float:<select class="imageFloat"><option value="C">Center</option><option value="R">Right</option><option value="L">Left</option></select></span> <a href="javascript:;" class="geoeditorauthorbutton_send">Edit Done</a></div>')
.prev().find('a.geoeditorauthorbutton_send').click(function(){
var sizeParam = 'full';
var sizeValue = jQuery(this).parent().find('.imageSize').val();
if(jQuery(this).parent().find('input.isSquare').attr('checked')){
sizeParam = "sq";
if(sizeValue ==="tiny"){
sizeParam += "150";
}else if(sizeValue ==="small"){
sizeParam += "300";
}else if(sizeValue ==="medium"){
sizeParam += "384";
}else if(sizeValue ==="large"){
sizeParam += "480";
}else {
sizeParam += "500";
}
}else{
sizeParam = sizeValue;
}
sizeParam += jQuery(this).parent().find('.imageFloat').val();
var geoREX = new RegExp(geoname+"[^>]*");
tiddler.set(tiddler.title,tiddler.text.replace(geoREX,geoname+" "+sizeParam),config.options.txtUserName,new Date());
if(Emathbook.options.pages[0]["defaultlang"] === Emathbook.options.pages[0].lang){
var translatedGeoeditors = "";
var translatedEditor = "";
var geoTranslations = store.reverseLookup('translation',tiddler.title.replace('_data',''),true);
for(var i=0;i<geoTranslations.length;i++){
geoTranslations[i].set(geoTranslations[i].title,geoTranslations[i].text.replace(geoREX,geoname+" "+sizeParam),config.options.txtUserName,new Date());
translatedGeoeditors = DataTiddler.getData(geoTranslations[i].title, 'geoeditors',[]);
translatedEditor = jQuery.extend(true, [], translatedGeoeditors[geoname]);
if(JSON.stringify(editor) == JSON.stringify(translatedEditor)){
var geodata = tool.geoelement.geoeditor('getContent');
translatedGeoeditors[geoname] = geodata[0];
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(geoTranslations[i].title, 'geoeditors', translatedGeoeditors, {});
config.options.chkAutoSave = autosavestatus;
}
tool.sendFifo.push({"title": geoTranslations[i].title, "newTiddler": 0});
}
}
jQuery('#actionButtons .actionmenu.menuopen button#actionbutton_Edit').click();
tool.sendGeoeditor();
jQuery(this).parents('.geoeditorauthorbuttons').remove();
}).button();
jQuery('.geoeditorauthorbuttons').css('border-top','2px solid red').css('border-left','2px solid red').css('border-right','2px solid red');
if (geosize){
var sizeParam = geosize;
if(sizeParam.substr(sizeParam.length-1) === "R" ){
jQuery('.geoeditorauthorbuttons .imageFloat').val('R');
sizeParam = sizeParam.substr(0,sizeParam.length-1);
} else if( sizeParam.substr(sizeParam.length-1) === "L"){
jQuery('.geoeditorauthorbuttons .imageFloat').val('L');
sizeParam = sizeParam.substr(0,sizeParam.length-1);
} else if( sizeParam.substr(sizeParam.length-1) === "C"){
jQuery('.geoeditorauthorbuttons .imageFloat').val('C');
sizeParam = sizeParam.substr(0,sizeParam.length-1);
}
if(sizeParam === "tiny" ||sizeParam === "small" ||sizeParam === "medium" ||sizeParam === "large" ||sizeParam === "full" ){
jQuery('.geoeditorauthorbuttons .imageSize').val(sizeParam);
}else if(sizeParam.substr(0,2)==="sq"){
jQuery('.geoeditorauthorbuttons span.sizeSlect input.isSquare').attr('checked','checked');
options.mode="square";
var imgHeight=(sizeParam.substr(2) === parseInt(sizeParam.substr(2))+''?parseInt(sizeParam.substr(2)):500);
if(imgHeight < 151){
jQuery('.geoeditorauthorbuttons .imageSize').val('tiny');
}else if(imgHeight < 301){
jQuery('.geoeditorauthorbuttons .imageSize').val('small');
}else if(imgHeight < 385){
jQuery('.geoeditorauthorbuttons .imageSize').val('medium');
}else if(imgHeight < 481){
jQuery('.geoeditorauthorbuttons .imageSize').val('large');
}else {
jQuery('.geoeditorauthorbuttons .imageSize').val('full');
}
}else if(sizeParam.match(/w[0-9]+h[0-9]+/)){
jQuery('.geoeditorauthorbuttons span.sizeSlect').hide();
}
}else{
jQuery('.geoeditorauthorbuttons .imageSize').val('full');
}
tool.geoelement.geoeditor('init', options);
tool.geoelement.bind('geoeditor_changed', function(e){
var geoeditors = DataTiddler.getData(tool.tiddlerName, 'geoeditors', {});
var geodata = jQuery(this).geoeditor('getContent');
geoeditors[geoname] = geodata[0];
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(tool.tiddlerName, 'geoeditors', geoeditors, {});
config.options.chkAutoSave = autosavestatus;
});
jQuery('.geoeditorauthorbuttons span.sizeSlect input.isSquare').change(function(){
options.scenes = tool.geoelement.geoeditor('getContent')[0];
if(jQuery(this).attr('checked')){
options.mode="square";
}else{
options.mode="full";
}
tool.geoelement.geoeditor('init', options);
});
jQuery('div.editthis').remove();
jQuery('div.translatethis').remove();
});
/***************************************************
** Signchart edit Mode **
***************************************************/
signchartviews.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.signchart = jQuery(this).parents('.pssignchartwrapper');
tool.signchart.css('position','relative');
var chartId = tool.signchart.attr('class').replace(/^.*pssc_/,'').split(' ')[0];
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
jQuery('div.editthis').remove();
tool.signchart.before('<div class="sdauthorbuttons"><a href="javascript:;" class="signchart_send">'+EbookDictionary.localize('edit done')+'</a></div>')
.prev().find('a.signchart_send').click(function(){
jQuery('#actionButtons .actionmenu.menuopen button#actionbutton_Edit').click();
jQuery('#pageOneNavi').show();
tool.callNext();
}).button();
var tiddlerName = tool.signchart.parents('[tiddler]').attr('tiddler');
var tiddler = store.getTiddler(tiddlerName);
tool.oldcontent = tiddler.text;
tool.cancel = function(){
tiddler.set(null, tool.oldcontent);
autoSaveChanges();
}
tool.sendFifo.push({"title": tiddlerName, "newTiddler": 0});
var settings = jQuery.extend(true, {},DataTiddler.getData(tiddler, 'signchart',{}));
settings[chartId] = settings[chartId] || {rows:[], total:{}, intervals:[], rootpoints:[], undefinedpoint: []};
var startoptions = {"mode":"edit"};
tool.signchart
.pssignchart(startoptions)
.pssignchart('set',settings[chartId])
.bind('pssc_changed', function(e){
var $psscplace = jQuery(this);
var data = $psscplace.pssignchart('get');
var settings = DataTiddler.getData(tiddler, 'signchart',{});
settings[chartId] = data;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tiddler.setData('signchart', settings);
config.options.chkAutoSave = autosavestatus;
});
});
/***************************************************
** Sd-Editor edit Mode **
***************************************************/
editorviews.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.qedelem = jQuery(this).parents('.qededitor');
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
jQuery('div.editthis').remove();
tool.qedelem.before('<div class="sdauthorbuttons"><a href="javascript:;" class="sdauthorbutton_send">Send SD</a></div>')
.prev().find('a.sdauthorbutton_send').click(function(){
jQuery(this).parents('.sdauthorbuttons').remove();
jQuery('#actionButtons .actionmenu.menuopen button#actionbutton_Edit').click();
tool.sendSd();
}).button();
var tiddlerName = tool.qedelem.parents('[tiddler]').attr('tiddler');
var tiddler = store.getTiddler(tiddlerName);
tool.oldcontent = tiddler.text;
tool.cancel = function(){
tiddler.set(null, tool.oldcontent);
autoSaveChanges();
}
tool.sendFifo.push({"title": tiddlerName, "newTiddler": 0});
tool.qedelem.find('.qededitorbuttons a.command_qededit').click();
});
/***************************************************
** Subelements translate Mode **
** -hint **
** -extra **
***************************************************/
translateSubs.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
jQuery('.extraboxwrapper .extraboxclose').click();
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var dataTiddler = store.getTiddler(tool.tiddlerName);
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
tool.openDialog('translatecontent', 'Translate selected content', ['elem_content', 'tag_insert']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.elem_content').append('<p class="translatealert">'+translatealert+'</p><h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea>');
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
var translatedTiddlername = tool.tiddlerName+'_'+Emathbook.options.pages[0]["lang"];
var translatedTiddler = store.createTiddler(translatedTiddlername);
this.saveTiddler(translatedTiddlername, content, dataTiddler.tags,(dataTiddler.fields.ebooktitle)?dataTiddler.fields.ebooktitle:"",null,{"translation":tool.tiddlerName});
this.sendFifo.push({"title": translatedTiddlername, "newTiddler": 1});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
/***************************************************
** Subelements edit Mode **
** -hint **
** -extra **
***************************************************/
subelements.not(translateSubs).append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
//alert();
tool.tiddlerName = jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
jQuery('.extraboxwrapper .extraboxclose').click();
/*if(Emathbook.options.pages[0]["lang"]==Emathbook.options.pages[0]["defaultlang"]){
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data');
}else{
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data_'+Emathbook.options.pages[0]["lang"]);
dataTiddler.fields.translation = tool.tiddlerName+'_data';
}*/
var dataTiddler = store.getTiddler(tool.tiddlerName);
tool.openDialog('editcontent', 'Edit selected content', ['bigElem','elem_content', 'tag_insert','original_content','default_content']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea><p>Box title can be added by adding <i style="border:1px solid black;border-radius:4px;padding:2px;">"extratitle":"Title" <b style="color:red;">,</b></i> to beging of the <i style="border:1px solid black;border-radius:4px;padding:2px;"><data>{}</data></i> element. <b><span style="text-decoration:underline">Notice</span> that there is ,</b>.</p><p>If there is no <i style="border:1px solid black;border-radius:4px;padding:2px;"><data>{}</data></i> create it to end of content like <i style="border:1px solid black;border-radius:4px;padding:2px;"><data>{"extratitle":"Title"}</data></i></p>');
var bigboxcheck = tool.dialogbox
.find('.bigElem')
.append('<h2>Show on second page</h2><input class="isBigbox" type="checkbox" /><span class="plusinfo">(Default display in pop-up box)</span>').find('.isBigbox');
if(dataTiddler.isTagged('bigbox')){
bigboxcheck.attr('checked','checked');
}
if (typeof(jQuery.fn.emathonoff) === 'function'){
bigboxcheck.emathonoff({
texts: ['yes','no'],
coloron: 'green',
coloroff: 'red'
});
}
tool.dialogbox.find('.original_content')
.append('<button class="open_original">Before editing</button><div class="original_text hidden_original">'+dataTiddler.text.replace(/</g,'<').replace(/>/g,'>')+'</div>')
.find('button.open_original').click(function(){
var textBox = jQuery(this).parent().children('.original_text');
if(textBox.hasClass('hidden_original')){
textBox.removeClass('hidden_original');
}else{
textBox.addClass('hidden_original');
}
});
/*
if(Emathbook.options.pages[0]["lang"]!==Emathbook.options.pages[0]["defaultlang"]){
tool.dialogbox.find('.default_content')
.append('<button class="open_default">Original ('+Emathbook.options.pages[0]["defaultlang"]+')</button><div class="original_text hidden_default">'+store.getTiddlerText(tool.tiddlerName+'_data').replace(/</g,'<').replace(/>/g,'>')+'</div>')
.find('button.open_default').click(function(){
var textBox = jQuery(this).parent().children('.original_text');
if(textBox.hasClass('hidden_default')){
textBox.removeClass('hidden_default');
}else{
textBox.addClass('hidden_default');
}
});
}
*/
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
try{
var elementData = content.split('<data>')[1].replace('</data>','');
var canParse = JSON.parse(elementData);
}catch(e){
alert('Check dataobject format!');
return false;
}
dataTiddler.set(dataTiddler.title,null,null,null,('ebook'+this.elemtype+(this.dialogbox.find('.isBigbox').attr('checked')?' bigbox':'')).split(' '));
this.saveTiddler(dataTiddler.title, content, [],'', null, dataTiddler.fields);
this.sendFifo.push({"title": dataTiddler.title, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis,#pageTwoWrapper .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
return false;
});
ebookimages.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var imagesName = store.getTiddlerText(tool.tiddlerName+'##image').replace('[img[','').replace(']]','');
var imagesCaption = store.getTiddlerText(tool.tiddlerName+'##caption');
var imagesSizex = store.getTiddlerText(tool.tiddlerName+'##size-x');
var imagesSizey = store.getTiddlerText(tool.tiddlerName+'##size-y');
tool.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
// var tool = this;
tool.dialogbox.find('.tag_insert').append('Insert tags <input value="'+jQuery.trim(store.getTiddler(tool.tiddlerName).getTags().replace('bookimage','').replace('data',''))+'" class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input value="'+imagesSizex+'" class="x_size_input" type="text"/><b>px</b>');
tool.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input value="'+imagesSizey+'" class="y_size_input" type="text"/><b>px</b>');
tool.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox">'+imagesCaption+'</span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
tool.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" checked="checked" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li[imageTiddler="'+imagesName+'"]').addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imagesName+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
tool.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
initImageList(selectedImageTiddlers);
});
tool.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+((parseInt(this.dialogbox.find('.x_size input.x_size_input').val()) > 0)? this.dialogbox.find('.x_size input.x_size_input').val():"")+"\n!size-y\n"+((parseInt(this.dialogbox.find('.y_size input.y_size_input').val()) > 0)? this.dialogbox.find('.y_size input.y_size_input').val():"");
this.saveTiddler(tool.tiddlerName, content, ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),'');
this.sendFifo.push({"title": tool.tiddlerName, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
jQuery('div.editthis').remove();
});
translateImages.append('<div class="translatethis"><a href="javascript:;" title="Translate this element"><span>Translate</span></a></div>')
.find('.translatethis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var origlang = Emathbook.options.pages[0].defaultlang;
var translang = Emathbook.options.pages[0].lang;
var translatealert = EbookDictionary.localize('youre translating').format([origlang, translang]);
var imagesName = store.getTiddlerText(tool.tiddlerName+'##image').replace('[img[','').replace(']]','');
var imagesCaption = store.getTiddlerText(tool.tiddlerName+'##caption');
var imagesSizex = store.getTiddlerText(tool.tiddlerName+'##size-x');
var imagesSizey = store.getTiddlerText(tool.tiddlerName+'##size-y');
tool.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
// var tool = this;
tool.dialogbox.find('.tag_insert').append('Insert tags <input value="'+jQuery.trim(store.getTiddler(tool.tiddlerName).getTags().replace('bookimage','').replace('data',''))+'" class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input value="'+imagesSizex+'" class="x_size_input" type="text"/><b>px</b>');
tool.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input value="'+imagesSizey+'" class="y_size_input" type="text"/><b>px</b>');
tool.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox">'+imagesCaption+'</span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
tool.dialogbox.find('.imageSelect').append('<p class="translatealert">'+translatealert+'</p><h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" checked="checked" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li[imageTiddler="'+imagesName+'"]').addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imagesName+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
tool.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
initImageList(selectedImageTiddlers);
});
tool.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+((parseInt(this.dialogbox.find('.x_size input.x_size_input').val()) > 0)? this.dialogbox.find('.x_size input.x_size_input').val():"")+"\n!size-y\n"+((parseInt(this.dialogbox.find('.y_size input.y_size_input').val()) > 0)? this.dialogbox.find('.y_size input.y_size_input').val():"");
this.saveTiddler(tool.tiddlerName + "_" + Emathbook.options.pages[0]["lang"], content, ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),'');
this.sendFifo.push({"title": tool.tiddlerName + "_" + Emathbook.options.pages[0]["lang"], "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
jQuery('div.editthis').remove();
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('editelems');",30);
}
//}}}
//{{{
/*******************************************************************
* author-order.js
* Authortools for TiddlyWiki-ebook
* to order existing content on the page
* Petri Salmela
* Petri Sallasmaa
* 15.01.2013
* depends: jQuery, jQueryUI
*******************************************************************/
Authortool.prototype.orderElement = function(){
/************************************************************
* Tool for ordering elements in chapter/section/subsection
************************************************************/
var tool = this;
var $page;
var $pageElemens;
this.assignmentlist = (jQuery('#pageOne').find('.sdbookassignmentlist').length !== 0);
if (!this.assignmentlist){
$page = jQuery('#pageOne > [tiddler]');
$pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
$pageElements.each(function(){
var elem = jQuery(this);
var height = elem.height();
elem.attr('origheight', height);
})
$pageElements.prepend('<div class="movethis">Drag me<a href="javascript:;" class="embutton showhide"></a></div>');
$page.addClass('orderelems').sortable({
placeholder: "ui-state-highlight"
}).disableSelection();
$pageElements.find('a.showhide').click(function(){
var $parent = jQuery(this).parents('[tiddler]').eq(0);
if ($parent.hasClass('isopen')){
$parent.animate({'height': '150'},300, function(){jQuery(this).removeClass('isopen').attr('style','');});
} else {
$parent.css('height', 'auto');
var height = $parent.height();
$parent.css('height', 150);
$parent.animate({'height': height}, 300, function(){jQuery(this).addClass('isopen').attr('style','');});
}
});
} else {
}
}
Authortool.prototype.orderElementDo = function(){
var tool = this;
if (!tool.assignmentlist){
var elemlist = tool.getElementList();
var tiddler = jQuery('#pageOne > [tiddler]').attr('tiddler');
tool.setChapterContent(tiddler, elemlist);
tool.sendFifo.push({"title": tiddler, "newTiddler": 0});
tool.callNext();
}
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#pageOneNavi').show();
jQuery('#actionmenu_Order.menuopen #actionbutton_Order').click();
}
Authortool.prototype.getElementList = function(){
/************************************************************
* Get name of element tiddlers on the page. Return an array.
************************************************************/
var tool = this;
var $pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
var tiddlers = [];
for (var i = 0; i < $pageElements.length; i++){
tiddlers.push($pageElements.eq(i).attr('tiddler'));
}
return tiddlers;
}
Authortool.prototype.setChapterContent = function(tiddlername, tiddlerlist){
var tool = this;
if (store.tiddlerExists(tiddlername)){
var chapterTiddler = store.getTiddler(tiddlername);
var text = '<<tiddler ' + tiddlerlist.join('>>\n<<tiddler ') + '>>';
chapterTiddler.set(chapterTiddler.title, text);
}
}
//}}}
/***
|Name|author-remove.js|
|Version|1.0|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|Authortools for TiddlyWiki-ebook remove functionality of authoring|
!!!!!Revisions
<<<
20130819.1207 ''Version 1.0'' ''add''
* Added modelsolution remove
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* author-remove.js
* Authortools for TiddlyWiki-ebook
* to remove elements
* Petri Salmela
* Petri Sallasmaa
* 8.11.2011
* depends: jQuery, jQueryUI
*******************************************************************/
Authortool.prototype.removeModelsolution = function(){
/******************************************************
* Tool for remove modelsolution
******************************************************/
this.workingDialog(EbookDictionary.localize('deleting'));
var thisTiddler = store.getTiddler(this.tiddlerName);
thisTiddler.fields.emathbookid = -1;
thisTiddler.fields.modelsolutionto = "";
thisTiddler.set();
this.sendFifo.push({"title": thisTiddler.title, "newTiddler": 0,"system":3});
this.callNext();
}
Authortool.prototype.removeElement = function(){
/******************************************************
* Tool for remove element in chapter/section/subsection
******************************************************/
this.assignmentlist = (jQuery('#pageOne').find('.sdbookassignmentlist').length != 0);
if (!this.assignmentlist){
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
var elementType = '[tiddler]';
}else{
var pageElements = jQuery('#pageOne .sdbookassignmentlist .assignmentAccordion0 h3,#pageOne .sdbookassignmentlist .otherassignmentAccordion h3');
var elementType = 'h3';
}
if (pageElements.length == 0){
alert('Nothing to remove.'); //Localization
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
return false;
}
var tool = this;
this.removeElemdata = {
'pageview': (!this.assignmentlist)?jQuery('#pageOne > [tiddler]').attr('tiddler'):jQuery('#pageOne .ebookbox [tiddler]').attr('tiddler'), // chapter/section/subsection, where element is added
'removedElems': [] // What Elem to remove
};
pageElements.append('<div class="removethis"><a href="javascript:;" title="Remove this element"><span>X</span></a></div>').end()
.find('.removethis a').click(function(){
if(jQuery(this).parent().hasClass('selectedRemove')){
tool.removeElemdata.removedElems.remove(jQuery(this).parents(elementType).eq(0).attr('tiddler'));
jQuery(this).parent().removeClass('selectedRemove');
}else{
jQuery(this).parent().addClass('selectedRemove')
tool.removeElemdata.removedElems.push(jQuery(this).parents(elementType).eq(0).attr('tiddler'));
}
return false;
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('removeelems');",30);
}
Authortool.prototype.removeInTiddler = function(){
/******************************************************
* Tool for removing <<tiddler>>-macro in chapter/section/subsection
******************************************************/
if(this.removeElemdata.removedElems==[]){
this.callNext();
return false;
}
var tiddler = store.getTiddler(this.removeElemdata.pageview);
var content = tiddler.text;
var reftiddler = '';
var reExp;
var removedtiddlerList = [];
for(var i=0;i<this.removeElemdata.removedElems.length;i++){
if (!this.assignmentlist){
reftiddler = '<<tiddler '+this.removeElemdata.removedElems[i]+'>>';
reExp = new RegExp(reftiddler+'[\n]*');
}else{
reftiddler = this.removeElemdata.removedElems[i];
reExp = new RegExp('\ '+reftiddler);
}
content = content.replace(reExp,'');
// This to function someday
removedtiddlerList.push(this.removeElemdata.removedElems[i]);
if(store.tiddlerExists(this.removeElemdata.removedElems[i]+'_data')){removedtiddlerList.push(this.removeElemdata.removedElems[i]+'_data');}
for(var j=0;j<EbookPages[0].ebook.altlangs.length;j++){
if(store.tiddlerExists(this.removeElemdata.removedElems[i]+'_data_'+EbookPages[0].ebook.altlangs[j])){removedtiddlerList.push(this.removeElemdata.removedElems[i]+'_data_'+EbookPages[0].ebook.altlangs[j]);}
if(store.tiddlerExists(this.removeElemdata.removedElems[i]+'_'+EbookPages[0].ebook.altlangs[j])){removedtiddlerList.push(this.removeElemdata.removedElems[i]+'_'+EbookPages[0].ebook.altlangs[j]);}
}
}
for(var i=0; i< removedtiddlerList.length;i++){
var oneTiddler = store.getTiddler(removedtiddlerList[i]);
oneTiddler.fields.emathbookid = '-1';
oneTiddler.set();
this.sendFifo.push({"title": removedtiddlerList[i], "newTiddler": 0});
}
var now = new Date();
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now);
autoSaveChanges();
this.sendFifo.push({"title": this.removeElemdata.pageview, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#pageOneNavi').show();
jQuery('#actionmenu_Remove').click();
this.callNext();
}
//}}}
/***
|''Name:''|authorCourseComments|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|EmathbookPage for E-math ebook|
|''Version:''|1.1|
|''Date:''|Sep 25, 2013|
|''Source:''|abcd|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130925.13.37 ''fix''
* update functionality fix
<<<
<<<
20130925.13.37 ''add''
* commentlist scrolls to rigth position
<<<
!!!!!Code
***/
//{{{
Emathbook.getCourseComments = function (bookid){
if (typeof(bookid)=="undefined"){
bookid = EbookPages[0].ebook.bookid;
}
var loadDialog = jQuery('body').append('<div id="loadBookscreen" title="'+EbookDictionary.localize('Loading...')+'..."><p class="currentState"></p></div>').find('#loadBookscreen');
loadDialog.dialog({
height: 200,
modal: true,
resizable: false,
closeOnEscape: false,
draggable: false
});
loadDialog.parent().find('.ui-dialog-titlebar-close').remove();
loadDialog.find('p.currentState').text(EbookDictionary.localize('Loading...'));
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var defaultcomms = {"lastCheck":{}};
defaultcomms.lastCheck[bookid] = 0;
var commdata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'coursecomment', defaultcomms);
var updateurl = configs.updateURL;
var lastCheck = "";
lastCheck = (commdata.lastCheck && commdata.lastCheck[bookid] || 0);
var userName = config.options.txtUserName;
var userKey = config.options.txtUserKey;
callback = function(data){
var loadscreen = loadDialog;
if (response.status == 200 && response.responseText !="Login Error"){
var serverTime = data.substring(0,data.indexOf('_'));
data = data.substring(data.indexOf('_') + 1).replace(/"pagecomment"/g,'"coursecomment"').replace(/commentto/g,'commentedebookid="'+bookid+'" coursecommentto');
var commelem = jQuery(data);
var numberOfUpdates = commelem.find('div[title]').length;
if(numberOfUpdates>0){
store.importTiddlyWiki(data);
if(!commdata.lastCheck){commdata.lastCheck={};}
commdata.lastCheck[bookid] = serverTime;
DataTiddler.setData(Emathbook.config.userdatatiddler, 'coursecomment', commdata);
loadscreen.find('p.currentState').text(EbookDictionary.localize('comments ready').format(numberOfUpdates, bookid));
}else{
loadscreen.find('p.currentState').text(EbookDictionary.localize('no updates available').format(numberOfUpdates, bookid));
}
loadscreen.dialog({ buttons: { "Ok": function() { setTimeout("refreshElements(jQuery('#pageTwo')[0]);jQuery('body').find('#loadBookscreen').remove();",1000); } } });
}else{
Emathbook.options.netconnection = false;
if(loadscreen.length > 0){
loadscreen.find('p.currentState').text(EbookDictionary.localize('connection error'));
setTimeout("jQuery('body').find('#loadBookscreen').remove();",2000);
}
}
}
var response = jQuery.postCORS(updateurl, {"getCourseComments":lastCheck, "bookid": bookid, "username": userName, "userkey":userKey}, callback);
testilogit.courseUpdate = response;
}
config.macros.showCourseCommentList = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var commentnavi = jQuery(place).append('<div id="coursecommentnavi"></div>').find('#coursecommentnavi');
var commentToId = "";
var hideHiddens = (tiddler.data() && tiddler.data().hidden) || 'hide';
var allPagecomments = store.reverseLookup('commentedebookid',EbookPages[0].ebook.bookid,true ,'-modified');
if(allPagecomments.length>0){
commentnavi = commentnavi.append('<ul id="commentList"></ul>').find('ul#commentList');
for (var i=0 ;i<allPagecomments.length;i++){
var subcomments = {"general":{"date": allPagecomments[i].modified,"hidden": (allPagecomments[i].isTagged('hidegeneral')?'hide':'show'), "text":allPagecomments[i].text.replace(/\n*<data>.*<\/data>\n*/,'')}};
jQuery.extend(subcomments, allPagecomments[i].data('pagecomments',{}));
for (var commtype in subcomments){
if (subcomments[commtype].text != ''){
if((hideHiddens ==='hide' && !(subcomments[commtype].hidden ==="hide"))||(hideHiddens ==='show')){
commentToId = EbookPages[0].ebook.getIdByTiddler(allPagecomments[i].fields.coursecommentto);
commentnavi.append('<li id="'+allPagecomments[i].title+commtype+'" class="'+commtype+' selectComment '+allPagecomments[i].fields.coursecommentto+(commentToId===EbookPages[0].currentpage?" thispageComment":"")+'" commentto="'+commentToId+'">'+(!(subcomments[commtype].hidden ==="hide")?'<button class="hideComment" commentType="'+commtype+'" commentTiddler="'+allPagecomments[i].title+'">'+EbookDictionary.localize('hide')+'</button>':'')+'<span class="commentSent">'+allPagecomments[i].modified+'</span>: <span class="commentSender">'+allPagecomments[i].creator+'</span> <span class="pagecommenttype">'+commtype+'</span> <span class="commentToText">'+EbookPages[0].ebook.getNumberedTitle(commentToId)+'</span></li>');
}
}
}
}
}
if(typeof(sessionStorage.courseCommentScrollto) !=="undefined"){
jQuery('#commentList').scrollTop(sessionStorage.courseCommentScrollto);
}
jQuery('#commentList').scroll(function() {
clearTimeout(jQuery.data(this, 'scrollTimer'));
jQuery.data(this, 'scrollTimer', setTimeout(function() {
sessionStorage.courseCommentScrollto = jQuery('#commentList').scrollTop();
}, 250));
});
commentnavi.find('.selectComment').click(function(){
EbookPages[0].setPage(jQuery(this).attr('commentto'));
});
commentnavi.find('.hideComment').click(function(){
var hidebutton = jQuery(this);
var commentType = hidebutton.attr('commentType');
var hideTiddler = store.getTiddler(hidebutton.attr('commentTiddler'));
if(commentType ==='general'){
hideTiddler.tags.push('hidegeneral');
hideTiddler.set();
hidebutton.parent().remove();
}else{
var commentData = hideTiddler.data('pagecomments');
commentData[commentType].hidden = 'hide';
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(hideTiddler ,'pagecomments', commentData,{});
hideTiddler.set();
config.options.chkAutoSave = autosavestatus;
}
refreshElements(jQuery("#pageTwo")[0]);
});
commentnavi.after('<button id="updatecoursecomments">'+EbookDictionary.localize('update from server')+'</button>');
jQuery('#pageTwo #updatecoursecomments').button().click(function(){
Emathbook.getCourseComments(EbookPages[0].ebook.bookid);
});
jQuery('#pageTwo #updatecoursecomments').after('<button id="showHidden">'+(hideHiddens ==='hide'?EbookDictionary.localize('Show hidden'):EbookDictionary.localize('Hide hidden'))+'</button>');
jQuery('#pageTwo #showHidden').button().click(function(){
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(tiddler.title, 'hidden', (hideHiddens ==='hide'?'show':'hide'),'hide');
tiddler.set();
config.options.chkAutoSave = autosavestatus;
refreshElements(jQuery("#pageTwo")[0]);
});
}
}
config.macros.showCourseComments = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var currentpage = EbookPages[0].getCurrentTiddlerName();
var text = '{{pagecommentlist{\n!'+EbookDictionary.localize('Comments on page')+'\n!!' + EbookPages[0].getNumberedTitle() + '\n';
var allcomments = store.reverseLookup('coursecommentto',currentpage,true,'modified');
for (var i = 0; i < allcomments.length; i++){
var subcomments = {"general":{"date": allcomments[i].modified, "text":allcomments[i].text.replace(/\n*<data>.*<\/data>\n*/,'')}};
jQuery.extend(subcomments, allcomments[i].data('pagecomments',{}));
for (var commtype in subcomments){
if (subcomments[commtype].text != ''){
text += '{{pagecommentblock '+commtype+(subcomments[commtype].hidden ==='hide' || (commtype ==='general' && allcomments[i].isTagged('hidegeneral'))?' hiddencommentblock':'')+'{\n{{pagecommenthead{\n{{pagecommenttype{'+commtype+'}}} {{pagecommentauthor{'+allcomments[i].creator+'}}} {{pagecommentdate{'+subcomments[commtype].date+'}}} }}}{{pagecommentbody'+(subcomments[commtype].hidden ==='hide' || (commtype ==='general' && allcomments[i].isTagged('hidegeneral'))?' hidecommentbody':' '+allcomments[i].title)+'{\n'+subcomments[commtype].text+'\n}}} }}}';
}
}
}
if (allcomments.length > 0 && jQuery('#pageOne h1.ebooktitle a.commentsnotify').length == 0){
var titleplace = jQuery('#pageOne h1.ebooktitle');
var commbutton = jQuery('<a href="javascript:;" class="commentsnotify"></a>');
wikify('[img[icon-comment.png]]',commbutton[0]);
commbutton.click(function(){
jQuery('#contentWrapper').removeClass('pageclosed');
DataTiddler.setData(Emathbook.config.userdatatiddler, 'pagetwovisible', true);
});
titleplace.append(commbutton);
}
text += '}}}\n{{eblinebreak{}}}';
wikify(text,place);
var hideHiddens = (tiddler.data() && tiddler.data().hidden) || 'hide';
if(((tiddler.data() && tiddler.data().hidden) || 'hide') ==='hide'){
jQuery(place).find('.hidecommentbody').hide().prev().append('<button class="showcommentbody">'+EbookDictionary.localize('show')+'</botton>');
jQuery(place).find('.showcommentbody').click(function(){
jQuery(this).parent().next().toggle();
});
}
jQuery(place).find('.pagecommentbody:not(.hidecommentbody)').append('<button class="hideComment">'+EbookDictionary.localize('hide')+'</button>');
jQuery(place).find('.hideComment').click(function(){
var hidebutton = jQuery(this);
var commentType = hidebutton.parent().parent().attr('class').replace('pagecommentblock ','');
var hideTiddler = store.getTiddler(hidebutton.parent().attr('class').replace('pagecommentbody ',''));
var oldmodified = hideTiddler.modified;
if(commentType ==='general'){
hideTiddler.tags.pushUnique('hidegeneral');
hideTiddler.set(null,null,null,oldmodified);
hidebutton.parent().remove();
}else{
var commentData = hideTiddler.data('pagecomments');
commentData[commentType].hidden = 'hide';
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(hideTiddler ,'pagecomments', commentData,{});
hideTiddler.set(null,null,null,oldmodified);
config.options.chkAutoSave = autosavestatus;
}
refreshElements(jQuery("#pageTwo")[0]);
});
}
}
//}}}
//{{{
/*******************************************************************
* authortools.js
* Authortools for TiddlyWiki-ebook
* NOT IN USE!!
* Petri Salmela
* Petri Sallasmaa
* 8.11.2011/14.3.2012
* depends: jQuery, jQueryUI
*******************************************************************/
/************************************************************************
* Authortool -class
************************************************************************/
function Authortool(callerElem){
if (typeof(callerElem) != 'undefined'){
this.callerElem = callerElem;
}
this.dialogbox;
this.save = function(){};
this.cancel = function(){};
this.bookid = EbookPages[0].ebook.bookid;
this.container = EbookPages[0].currentpage;
this.callFifo = [];
this.sendFifo = [];
this.assignmentlist = false;
}
Authortool.prototype.openDialog = function(dialogid, title, elements){
jQuery('body').append('<div id="authordialog_'+dialogid+'"></div>');
this.dialogbox = jQuery('#authordialog_'+dialogid);
for (var i = 0; i<elements.length; i++){
this.dialogbox.append('<div class="dialogelement '+elements[i]+'"></div>');
}
var tool = this;
this.dialogbox.dialog({
buttons: {
"Cancel": function(){
jQuery(this).dialog("destroy").remove();
tool.callFifo = [];
tool.removeLock();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
},
"Save": function(){if(tool.save()){jQuery(this).dialog("destroy").remove();}}
}, //Localization!!
width: 800,
height: 600,
autoOpen: true,
title: title,
close: function(){
jQuery(this).dialog("close").dialog("destroy").remove();
tool.removeLock();
}
});
}
Authortool.prototype.callNext = function(){
var nextf = this.callFifo.shift();
if (typeof(nextf) != 'undefined'){
this[nextf]();
}
}
Authortool.prototype.clearCallFifo = function(){
this.callFifo = [];
}
Authortool.prototype.closeDialog = function(dialogid){
jQuery('#authordialog_'+dialogid).dialog('destroy');
}
Authortool.prototype.findFreeTiddler = function(tidprefix){
/********************************************
* Returns next free tiddler name of format: tidprefix_number
********************************************/
var tidnumber = 0;
while (store.tiddlerExists(tidprefix+"_"+tidnumber)){tidnumber=tidnumber+1;}
return tidprefix + '_' + tidnumber;
}
Authortool.prototype.saveTiddler = function(tiddlerName, content, tags, ebooktitle){
var tiddler;
if (store.tiddlerExists(tiddlerName)){
tiddler = store.getTiddler(tiddlerName);
} else {
tiddler = store.createTiddler(tiddlerName);
}
for (var i = 0; i<tags.length; i++){
tiddler.tags.pushUnique(tags[i]);
}
var now = new Date();
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now,
tags,
tiddler.created,
{'ebooktitle': ebooktitle},
config.options.txtUserName);
//autoSaveChanges();
return tiddlerName;
}
Authortool.prototype.createSubsection = function(){
/******************************************************
* Tool for creating a new subsection
******************************************************/
this.tiddlerName = this.findFreeTiddler('subsection');
this.openDialog('addsubsection', 'Create new subsection', ['add_ebook_title', 'tag_insert']); // Localization
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.add_ebook_title').append('<h1>Subsection title:</h1><input type="text" class="add_ebook_title"/>');
this.save = function(){
var Ebook_title = this.dialogbox.find('input.add_ebook_title').val();
var subsecdata = {
'ebooktitle': Ebook_title,
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': ''
}
subsecdata.tags.push('subsection');
subsecdata.tags.push('container');
if (Ebook_title != ''){
subsecdata['content'] = '!!'+Ebook_title+'\n';
}
this.saveTiddler(this.tiddlerName, subsecdata.content, subsecdata.tags, subsecdata.ebooktitle);
return true;
}
return this.tiddlerName;
}
Authortool.prototype.pageComment = function(){
/******************************************************
* Tool for creating a new textelement
******************************************************/
this.tiddlerName = EbookPages[0].ebook.tocdict[EbookPages[0].currentpage].content + '_comment';
var commenttext = '';
if (store.tiddlerExists(this.tiddlerName)){
commenttext = store.getTiddler(this.tiddlerName).text;
}
this.openDialog('pagecomment', 'Comment this page', ['pagecomment','chk_sendserver']); // Localization
this.dialogbox.find('.pagecomment').append('<h1>My comment:</h1><textarea id="mypagecomment" name="mypagecomment" style="width: 100%;min-height:10em;">'+commenttext+'</textarea>');
this.dialogbox.find('.chk_sendserver').append('<label for="chksendcomment">Send comment to the server</label><input id="chksendcomment" checked="checked" type="checkbox" />');
this.save = function(){
var commentdata = {
'content': this.dialogbox.find('#mypagecomment').val(),
'tags': ['pagecomment']
}
this.saveTiddler(this.tiddlerName, commentdata.content, commentdata.tags, '');
if (this.dialogbox.find('#chksendcomment').attr('checked')){
Emathbook.sendContent(this.tiddlerName);
}
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createTextelement = function(){
/******************************************************
* Tool for creating a new textelement
******************************************************/
this.openDialog('addtextelement', 'Create new textelement', ['add_text_elem', 'tag_insert']); // Localization
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.add_text_elem').append('<h2>Text content:</h2><textarea class="add_text_elem"></textarea>');
this.save = function(){
var content = this.dialogbox.find('textarea.add_text_elem').val();
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<tiddler [[tiddlernameplaceholder_data]] >>'
}
this.elementcont.tags.push('textelement');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['textelement','data'],
'content': content
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.joinImageElement = function(){
/******************************************************
* Tool for joining preAttached image to the book
******************************************************/
this.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
var tool = this;
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input class="x_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input class="y_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" checked="checked" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li').eq(0).addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imageTiddlers[0].title+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
this.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
switch(jQuery(event.target).text()){
case 'Not fixed images':
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
case 'All images':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
case 'Choice tag':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
default:
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
}
initImageList(selectedImageTiddlers);
});
this.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+this.dialogbox.find('.x_size input.x_size_input').val()+"\n!size-y\n"+this.dialogbox.find('.y_size input.y_size_input').val();
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookgraph tiddlernameplaceholder image>>'
}
this.elementcont.tags.push('ebookgraph_image');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),
'content': content
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createSd = function(){
/******************************************************
* Tool for creating a new empty SD (inside examplebox).
******************************************************/
this.elementcont = {
'ebooktitle': '',
'tags': ['examplesd'],
'content': '<<ebookbox [[tiddlernameplaceholder_data]] examplesd>>'
}
this.elementcont.tags.push('examplebox');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['examplebox','data','examplesd'],
'content': '<<qedderiv examplesd0 savehere>>',
'data': {}
}
this.finishAuthoring();
return true;
}
Authortool.prototype.refreshTable = function(tnumber){
/******************************************************
* Refresh the nth table.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currenttable = 'table'+tnumber;
var tool = this;
var tdelem = {
'text':'<td><span class="mathquill-textbox tablecell"></span></td>',
'math':'<td><span class="mathquill-editable tablecell"></span></td>'
};
// var tablebody = this.dialogbox.find('.add_table_content table tbody').eq(tnumber);
var tablebody = this.dialogbox.find('.add_table_content.extable_'+tnumber+' table tbody, .questionTablefill[assignmenttable="'+tnumber+'"] table tbody');
tablebody.empty();
for (var i = 0; i<this.tables[currenttable].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables[currenttable].cols; j++){
lasttr.append(tdelem[this.tables[currenttable].types[i][j]]);
lasttr.find('td .mathquill-editable, td .mathquill-textbox').last().append(this.tables[currenttable].data[i][j]);
}
}
tablebody.find('.mathquill-editable').not('.mathquill-rendered-math').mathquill('editable');
tablebody.find('.mathquill-textbox').not('.mathquill-rendered-math').mathquill('textbox');
tablebody.find('.mathquill-editable').focusout(function(){
// var tnumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.add_table_content').eq(0));
var tparent = jQuery(this).parents('.add_table_content');
var tnumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tnumber = parseInt(tnumber);
var cell = jQuery(this);
var value = cell.mathquill('latex');//.replace(/\$([^\$]*)\$/g, '\\($1\\)');
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var tcell = cell.parents('td').eq(0);
var row = ttable.children('tbody').children('tr').index(trow);
var col = trow.children('td').index(tcell);
tool.tables['table'+tnumber].data[row][col] = value;
});
tablebody.parent().attr('class','').addClass(tool.tables['table'+tnumber].class);
}
Authortool.prototype.refreshTableTypes = function(tnumber){
/******************************************************
* Refresh the nth table in "types"-mode.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currenttable = 'table'+tnumber;
var tool = this;
// var tablebody = this.dialogbox.find('.add_table_content table tbody').eq(tnumber);
var tablebody = this.dialogbox.find('.add_table_content.extable_'+tnumber+' table tbody, .questionTablefill[assignmenttable="'+tnumber+'"] table tbody');
tablebody.empty();
for (var i = 0; i<this.tables[currenttable].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables[currenttable].cols; j++){
lasttr.append('<td class="tabletexttype"><span>'+this.tables[currenttable].types[i][j]+'</span></td>');
}
}
tablebody.find('td.tabletexttype').click(function(){
// var tnumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.add_table_content').eq(0));
var tparent = jQuery(this).parents('.add_table_content');
var tnumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tnumber = parseInt(tnumber);
var cell = jQuery(this);
var value = cell.text().toLowerCase();
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var row = parseInt(ttable.children('tbody').children('tr').index(trow));
var col = parseInt(trow.children('td').index(cell));
if (tool.tables['table'+tnumber].data[row][col] == ''){
tool.tables['table'+tnumber]['types'][row][col] = (value == 'text' ? 'math':'text');
tool.refreshTableTypes(tnumber);
} else {
alert('You can only change the type of empty cells.');
}
});
tablebody.parent().attr('class','').addClass(this.tables[currenttable].class);
}
Authortool.prototype.refreshNline = function(nlnumber){
/******************************************************
* Refresh the nth numberline.
******************************************************/
if (typeof(tnumber) == 'undefined'){
tnumber = 0;
}
var currentnline = 'nline'+nlnumber;
var tool = this;
var nlelem = this.dialogbox.find('.add_nline_content').eq(nlnumber).find('.nlinecontainer');
nlelem.empty();
var numline = new EmathbookNumberline();
numline.setdata(this.nlines['nline'+nlnumber]);
numline.create(nlelem);
}
Authortool.prototype.createExample = function(){
/******************************************************
* Tool for creating a new examplebox
******************************************************/
var tool = this;
this.openDialog('addexamplebox', 'Create new example', ['add_example_head', 'tag_insert', 'add_example_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_example_head')
.append('<h2>Example header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_example_elem')
.append('<h2>Example content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_derivation_button">Derivation</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem').append('<div><textarea class="example_elem add_example_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem').append('<div class="mathdisplaystyle"><span class="example_elem add_example_formula mathquill-editable"></span></div>').find('.mathquill-editable').mathquill('editable');
}).end()
.find('.add_derivation_button').click(function(){
var addexelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var sdnum = addexelem.find('.add_example_deriv').length;
addexelem.append('<div><div class="example_elem add_example_deriv exderiv_'+sdnum+'"></div></div>');
wikify('<<qedderiv examplesd'+sdnum+'>>', addexelem.find('.add_example_deriv.exderiv_'+sdnum)[0]);
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
addelem.append('<div><div class="example_elem add_example_graph" style="border:1px solid black;"><div class="graphcontainer"></div><span style="display:none;" class="graphdata"></span></div></div>');
addelem = addelem.find('.add_example_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
addelem.append('<div><div class="example_elem add_example_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_example_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var tablenum = addelem.find('.add_table_content').length;
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.append('<div class="table_container"><div class="example_elem add_table_content extable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addexamplebox').find('.add_example_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="example_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_example_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();// Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] example>>'
}
this.elementcont.tags.push('examplebox');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['examplebox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_example_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var elements = this.dialogbox.find('.example_elem');
var examplederiv_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_example_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_example_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_example_deriv')){
this.elementdata.content += '<<qedderiv examplesd'+examplederiv_number+' savehere>>\n';
if (typeof(this.elementdata.data.derivations) == 'undefined'){
this.elementdata.data.derivations = {};
}
var exsdeditor = elements.eq(i).find('.qededitor')[0].editor;
var derdata = exsdeditor.derivation.getSaveData();
for (var j=0; j<derdata.length; j++){
this.elementdata.data.derivations[derdata[j].name] = derdata[j].data;
exsdeditor.deleteDeriv(derdata[j].name);
}
examplederiv_number++;
} else if (elements.eq(i).hasClass('add_example_graph')){
this.elementdata.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementdata.data.graphs) == 'undefined'){
this.elementdata.data.graphs = {};
}
this.elementdata.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (elements.eq(i).hasClass('add_table_content')){
this.elementdata.content += '<<ebooktable table'+tablecount+' '+this.tables['table'+tablecount].class+' savehere>>\n';
if (tablecount == 0){
this.elementdata.data.table = this.tables;
}
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_example_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createTheory = function(){
/******************************************************
* Tool for creating a new theorybox
* TODO: combine more with createExample
******************************************************/
var tool = this;
this.tiddlerName = this.findFreeTiddler('theorybox');
this.openDialog('addtheorybox', 'Create new theory', ['add_theory_head', 'tag_insert', 'add_theory_elem', 'add_button_bar']); // Localization
this.dialogbox
.find('.add_theory_head')
.append('<h2>Theorybox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_theory_elem')
.append('<h2>Theorybox content:</h2>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Text</button><button class="add_displayform_button">Display formula</button><button class="add_graph_button">Graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem').append('<div><textarea class="theory_elem add_theory_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem').append('<div class="mathdisplaystyle"><span class="theory_elem add_theory_formula mathquill-editable"></span></div>').find('.mathquill-editable').mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
addelem.append('<div><div class="theory_elem add_theory_graph" style="border:1px solid black;"><div class="graphcontainer"></div><span style="display:none;" class="graphdata"></span><div></div>');
addelem = addelem.find('.add_theory_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
addelem.append('<div><div class="theory_elem add_theory_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_theory_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
var tablenum = addelem.find('.add_table_content').length;
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.append('<div class="table_container"><div class="theory_elem add_table_content extable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addtheorybox').find('.add_theory_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="theory_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_theory_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset(); // Testing adding table
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] theory>>'
}
this.elementcont.tags.push('theorybox');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['theorybox','data'],
'content': '',
'data': {}
}
this.elementdata.content += '!' + this.dialogbox.find('.add_theory_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var elements = this.dialogbox.find('.theory_elem');
var theoryderiv_number = 0;
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_theory_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_theory_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_theory_deriv')){
this.elementdata.content += '<<qedderiv theorysd'+theoryderiv_number+' savehere>>\n';
theoryderiv_number++;
} else if (elements.eq(i).hasClass('add_theory_graph')){
this.elementdata.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementdata.data.graphs) == 'undefined'){
this.elementdata.data.graphs = {};
}
this.elementdata.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (elements.eq(i).hasClass('add_table_content')){
this.elementdata.content += '<<ebooktable table'+tablecount+' '+this.tables['table'+tablecount].class+' savehere>>\n';
if (tablecount == 0){
this.elementdata.data.table = this.tables;
}
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementdata.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_theory_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createAssignment = function(){
/******************************************************
* Tool for creating a new assignment
******************************************************/
this.tiddlerName = this.findFreeTiddler('assignment');
var result = {tiddler: '', level: 0, atype: ''};
var add_assignment_text_all={
'level': '<form><div class="assigment_level_changer"><input type="radio" id="level0" name="level" value=0 /><label for="level0">*</label> <input type="radio" id="level1" value=1 name="level" /><label for="level1">**</label> <input type="radio" id="level2" value=2 name="level" /><label for="level2">***</label></div></form>',
'tags': 'Insert tags <input class="tags_input" type="text"/>(separate tags with space)',
'title': '<div class="add_elem ebook_title">Additional title:<input type="text" class="add_ebook_title"/></div>'
}
var add_assignment_text = '<div class="add_elem assignmentText"><span class="mathquill-textbox"></span></div>';
var add_displayform_text = '<div class="add_elem mathdisplaystyle"><span class="theory_elem add_theory_formula mathquill-editable"></span></div>';
this.openDialog('addassignment', 'Create new assignment', ['add_assignment_level', 'add_assignment_title', 'tag_insert', 'add_assignment_elem', 'add_button_bar']); // Localization
this.dialogbox.siblings('.ui-dialog-buttonpane').find('button:contains("Save")').button('disable'); //Localization
var tool = this;
tool.dialogbox.find('.tag_insert').append(add_assignment_text_all.tags);
tool.dialogbox
.find('.add_assignment_level')
.append(add_assignment_text_all.level)
.find('.assigment_level_changer').buttonset();
tool.dialogbox
.find('.add_assignment_title')
.append(add_assignment_text_all.title);
tool.dialogbox
.find('.add_assignment_elem')
.append('<h2>Assignment text</h2>');
tool.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_text_button">Add text paragraph</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button></div>')
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem')
.append(add_assignment_text)
.find('.mathquill-textbox:not(mathquill-editable):last')
.mathquill('textbox')
.focus();
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem')
.append(add_displayform_text)
.find('.mathquill-editable:last')
.mathquill('editable')
.focus();
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
addelem.append('<div><div class="add_elem add_assignment_graph" style="border:1px solid black;"><div class="graphcontainer"></div><span style="display:none;" class="graphdata"></span></div></div>');
addelem = addelem.find('.add_assignment_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_table_button').click(function(){ // Testing adding table
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var tablenum = addelem.find('.add_table_content').length;
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.append('<div class="table_container"><div class="add_elem add_table_content extable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="add_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
addelem = addelem.find('.add_assignment_nline:last');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addassignment').find('.add_assignment_elem');
addelem.append('<div><div class="add_elem add_assignment_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_assignment_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
tool.dialogbox.siblings('.ui-dialog-buttonpane').find('button:contains("Save")').button('enable'); //Localization
//var assignmentdata;
tool.save = function(){
tool.assignmentdata = {
'ebooktitle': tool.dialogbox.find('.add_assignment_title input').val(),
'tags': tool.dialogbox.find('.tag_insert input.tags_input').val().split(" "),
'content': '',
'level': tool.dialogbox.find('input[name="level"]:checked').val(),
'atype': '0',
'graphdata' : {},
'data': {}
}
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var asselements = tool.dialogbox.find('.add_assignment_elem div.add_elem');
for (var i = 0; i<asselements.length; i++){
if (asselements.eq(i).hasClass('assignmentText')){
tool.assignmentdata.content += asselements.eq(i)
.find('.mathquill-editable')
.mathquill('latex')
.replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\n';
} else if (asselements.eq(i).hasClass('mathdisplaystyle')){
tool.assignmentdata.content += '\\[' + asselements.eq(i)
.find('.mathquill-editable')
.mathquill('latex')
.replace(/\$([^\$]*)\$/g,'\\($1\\)') + '\\]\n';
} else if (asselements.eq(i).hasClass('add_assignment_graph')){
tool.assignmentdata.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(tool.assignmentdata.data.graphs) == 'undefined'){
tool.assignmentdata.data.graphs = {};
}
tool.assignmentdata.data.graphs['graph'+graphcount] = JSON.parse(asselements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (asselements.eq(i).hasClass('add_table_content')){
this.assignmentdata.content += '<<ebooktable table'+tablecount+' '+this.tables['table'+tablecount].class+' savehere>>\n';
if (tablecount == 0){
this.assignmentdata.data.table = this.tables;
}
tablecount++;
} else if (asselements.eq(i).hasClass('add_nline_content')){
this.assignmentdata.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.assignmentdata.data.nline = this.nlines;
}
nlinecount++;
} else if (asselements.eq(i).hasClass('add_assignment_image')){
if (imagecount == 0){
this.assignmentdata.imagedata = [];
}
this.assignmentdata.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.assignmentdata.imagedata.push(JSON.parse(asselements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
if(typeof(tool.assignmentdata.level) == 'undefined'){
alert('Set assignment level');
return false;
}
tool.assignmentdata.tags.push('assignment');
tool.assignmentdata.content += '\n<data>{"assignmentType": '+tool.assignmentdata.atype+', "level": '+tool.assignmentdata.level+'}</data>';
this.requestLockType();
return false;
}
return this.tiddlerName;
}
Authortool.prototype.addAssignment = function(){
/******************************************************
* Tool for adding a new assignment
******************************************************/
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 1){
var tool = this;
tool.lockType = 'assignment';
this.assignmentSavehandler = function(){
var asslist = jQuery('#pageOne').find('.sdbookassignmentlist');
var accordiantiddlername = asslist.children('span[tiddler]').attr('tiddler');
var accordiantiddler = store.getTiddler(accordiantiddlername);
var regexp_replace= new RegExp("(<<assignmentAccordion[^>]*)>>","g");
accordiantiddler.set(accordiantiddler.title,
accordiantiddler.text.replace(regexp_replace,'$1 '+tool.tiddlerName+'>>'),
config.options.txtUserName,
new Date());
tool.sendFifo.push({"title": accordiantiddlername, "newTiddler": 1});
}
this.createAssignment();
} else {
alert('No assignments');
}
}
Authortool.prototype.saveAssignmentElements = function(){
/******************************************************
* Save assignmenttiddlers of new element and push to sendFifo.
******************************************************/
this.tiddlerName = this.findFreeTiddler(this.elemtype);
var tool = this;
switch(this.elemtype){
case "assignment":
if(typeof(this.assignmentdata.imagedata) != 'undefined'){
for(var i=0;i<this.assignmentdata.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.assignmentdata.content = this.assignmentdata.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.assignmentdata.imagedata[i].content, this.assignmentdata.imagedata[i].tags, this.assignmentdata.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.assignmentdata.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
this.saveTiddler(tool.tiddlerName, tool.assignmentdata.content, tool.assignmentdata.tags, tool.assignmentdata.ebooktitle);
for (datakey in this.assignmentdata.data){
DataTiddler.setData(tool.tiddlerName, datakey, this.assignmentdata.data[datakey], {});
}
//DataTiddler.setData(tool.tiddlerName, 'graphs', tool.assignmentdata.graphdata, {});
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.assignmentSavehandler();
break;
case "otherassignment":
if(typeof(this.elementcont.imagedata) != 'undefined'){
for(var i=0;i<this.elementcont.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.elementcont.content = this.elementcont.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.elementcont.imagedata[i].content, this.elementcont.imagedata[i].tags, this.elementcont.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.elementcont.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
var tempAssignmentName = "";
for(var i=0;i<tool.elementdata.length;i++){
tempAssignmentName=this.findFreeTiddler("assignment");
this.elementcont.content = this.elementcont.content.replace(tool.elementdata[i].placeHolder,tempAssignmentName);
this.elementdata[i].saveToTiddler(tempAssignmentName);
this.sendFifo.push({"title": tempAssignmentName, "newTiddler": 1});
}
tool.saveTiddler(tool.tiddlerName, tool.elementcont.content, tool.elementcont.tags, tool.elementcont.ebooktitle);
if(!jQuery.isEmptyObject(tool.elementcont.data)){
for (datakey in this.elementcont.data){
DataTiddler.setData(tool.tiddlerName, datakey, this.elementcont.data[datakey], {});
}
}
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.assignmentSavehandler();
break;
default:
alert('Something went wrong!');
}
this.callNext();
}
Authortool.prototype.finishAssignmentAuthoring = function(){
/******************************************************
* Finish adding element in chapter/section/subsection
******************************************************/
this.callFifo.push('getUpdates');
this.callFifo.push('saveAssignmentElements');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('removeLockType');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.addOtherassignment = function(){
/******************************************************
* Tool for adding a new 'other' typed assignment
******************************************************/
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 1){
DataTiddler.setData('QedDerivationsData','derivations',{});
var tool = this;
this.lockType = "assignment";
this.assignmentSavehandler = function(){
var asslist = jQuery('#pageOne').find('.sdbookassignmentlist');
var accordiantiddlername = asslist.children('span[tiddler]').attr('tiddler');
var accordiantiddler = store.getTiddler(accordiantiddlername);
if (accordiantiddler.text.match(/otherassignmentAccordion/g)){
var textList = accordiantiddler.text.split('\n');
var regexp_replace= new RegExp("(<<otherassignmentAccordion [^>]*)>>","g");
accordiantiddler.set(accordiantiddler.title,
textList[0].replace(regexp_replace,'$1 '+tool.tiddlerName+'>>\n')+textList[1],
config.options.txtUserName,
new Date());
}else{
accordiantiddler.set(accordiantiddler.title,
'<<otherassignmentAccordion '+tool.tiddlerName+'>>\n'+accordiantiddler.text,
config.options.txtUserName,
new Date());
}
tool.sendFifo.push({"title": accordiantiddlername, "newTiddler": 1});
}
this.createOtherassignment();
} else {
alert('No assignments');
}
}
Authortool.prototype.requestLockType = function(){
/**********************************************
* Request lock type
**********************************************/
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tool = this;
callback = function(data){
var datanum = parseInt(data);
if (datanum == -1){
if (confirm("Tallennus käynnissä. Odota ihan pieni hetki.")){return tool.requestLockType();}else{return false;}
} else {
tool.containerLockTypeId = datanum;
switch (tool.lockType){
case 'assignment':
tool.finishAssignmentAuthoring();
break;
case 'ebookimage':
tool.finishImageAuthoring();
break;
default:
break;
}
}
}
var response = jQuery.postCORS(updateurl, {"setContainerlock": this.lockType, "bookName": this.bookid, "author": config.options.txtUserName}, callback);
testilogit.lockTyperesp = response;
}
Authortool.prototype.removeLockType = function(){
/**********************************************
* Remove lock type
**********************************************/
if (typeof(this.containerLockTypeId) != 'undefined'){
var lockid = this.containerLockTypeId;
} else {
var lockid = 'all';
}
var tool = this;
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var response = jQuery.postCORS(updateurl, {"removeContainerlock":lockid, "bookName": this.bookid, "author": config.options.txtUserName, "container": this.lockType}, function(){tool.callNext();});
testilogit.lockTyperesp = response;
}
Authortool.prototype.createTableElem = function(){
/******************************************************
* Tool for creating new table element (.ebooktable)
******************************************************/
testilogit.crtable = this;
var tool = this;
this.openDialog('addtableelembox', 'Create new table element', ['add_table_caption', 'add_table_content', 'add_table_edittypes', 'tag_insert']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_table_caption')
.append('<h2>Table caption:</h2><span class="tablecaption mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_table_edittypes')
.append('<a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a>')
.find('a.edittypebutton')
.click(function(){
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable();
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes();
}
})
.button();
this.dialogbox
.find('.add_table_content')
.append('<table><tbody></tbody></table>');
var tdelem = {
'text':'<td><span class="mathquill-textbox tablecell"></span></td>',
'math':'<td><span class="mathquill-editable tablecell"></span></td>'
};
this.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
this.refreshTable = function(){
var tablebody = this.dialogbox.find('.add_table_content table tbody');
tablebody.empty();
for (var i = 0; i<this.tables['table0'].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables['table0'].cols; j++){
lasttr.append(tdelem[this.tables['table0'].types[i][j]]);
lasttr.find('td .mathquill-editable, td .mathquill-textbox').last().append(this.tables['table0'].data[i][j]);
}
}
tablebody.find('.mathquill-editable').not('.mathquill-rendered-math').mathquill('editable');
tablebody.find('.mathquill-textbox').not('.mathquill-rendered-math').mathquill('textbox');
tablebody.find('.mathquill-editable').focusout(function(){
var cell = jQuery(this);
var value = cell.mathquill('latex');//.replace(/\$([^\$]*)\$/g, '\\($1\\)');
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var tcell = cell.parents('td').eq(0);
var row = ttable.children('tbody').children('tr').index(trow);
var col = trow.children('td').index(tcell);
tool.tables['table0'].data[row][col] = value;
});
tablebody.parent().attr('class','').addClass(this.tables['table0'].class);
}
this.refreshTableTypes = function(){
var tablebody = this.dialogbox.find('.add_table_content table tbody');
tablebody.empty();
for (var i = 0; i<this.tables['table0'].rows; i++){
tablebody.append('<tr></tr>');
var lasttr = tablebody.find('tr').last();
for (var j = 0; j<this.tables['table0'].cols; j++){
lasttr.append('<td class="tabletexttype"><span>'+this.tables['table0'].types[i][j]+'</span></td>');
}
}
tablebody.find('td.tabletexttype').click(function(){
var cell = jQuery(this);
var value = cell.text().toLowerCase();
var ttable = cell.parents('table').eq(0);
var trow = cell.parents('tr').eq(0);
var row = parseInt(ttable.children('tbody').children('tr').index(trow));
var col = parseInt(trow.children('td').index(cell));
if (tool.tables['table0'].data[row][col] == ''){
tool.tables['table0']['types'][row][col] = (value == 'text' ? 'math':'text');
tool.refreshTableTypes();
} else {
alert('You can only change the type of empty cells.');
}
});
tablebody.parent().attr('class','').addClass(this.tables['table0'].class);
}
this.save = function(){
this.tables['table0'].caption = this.dialogbox.find('.add_table_caption .tablecaption').mathquill('latex').replace(/\$([^\$]*)\$/g, '\\($1\\)');
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebooktable [[tiddlernameplaceholder_data]] '+this.tables['table0'].class+'>>'
}
this.elementcont.tags.push('ebooktable');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['ebooktable','data'],
'content': '',
'data': {"table": this.tables}
};
this.finishAuthoring();
return true;
}
var tableopttool = new Authortool();
tableopttool.parent = this;
tableopttool.createTable(this.tables['table0']);
}
Authortool.prototype.createTable = function(returnobj, tnumber){
/******************************************************
* Tool for creating new table
******************************************************/
var tableClasses = ['default_table','value_table', 'theorytable','no_borders'];
var classHtml = '';
if (tableClasses.length > 0){
classHtml += '<select class="table_class">';
for (var i = 0; i<tableClasses.length; i++){
classHtml += '<option value="'+tableClasses[i]+'">'+tableClasses[i]+'</option>';
}
classHtml += '</select>';
}
this.openDialog('addtablebox', 'Create new table', ['add_table_options', 'table_example']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.table_example')
.append('<table><tbody><tr><td>value</td><td>value</td></tr><tr><td>value</td><td>value</td></tr></tbody></table>');
this.dialogbox
.find('.add_table_options')
.append('<h2>Options:</h2>\n<div><div class="table_cols_label">cols: <span class="table_cols_value">2</span></div><div class="table_cols"></div><div class="table_rows_label">rows: <span class="table_rows_value">2</span></div><div class="table_rows"></div><h2>Style:</h2>'+classHtml+'</div>')
.find('.table_rows').slider({
min: 1,
max: 20,
value: 2,
slide: function(event, ui){
jQuery(this).parents('.add_table_options').find('.table_rows_label .table_rows_value').empty().append(ui.value);
var tablecontent = jQuery('<tbody></tbody>');
var rowsnum = ui.value;
var colsnum = dialogbox.find('.table_cols').slider('value');
for (var i = 0; i<rowsnum; i++){
tablecontent.append('<tr></tr>');
var row = tablecontent.find('tr').last();
for (var j=0; j<colsnum; j++){
row.append('<td>value</td>');
}
}
dialogbox.find('.table_example table').empty().append(tablecontent);
}
}).end()
.find('.table_cols').slider({
min: 1,
max: 10,
value: 2,
slide: function(event, ui){
jQuery(this).parents('.add_table_options').find('.table_cols_label .table_cols_value').empty().append(ui.value);
var tablecontent = jQuery('<tbody></tbody>');
var rowsnum = dialogbox.find('.table_rows').slider('value');
var colsnum = ui.value;
for (var i = 0; i<rowsnum; i++){
tablecontent.append('<tr></tr>');
var row = tablecontent.find('tr').last();
for (var j=0; j<colsnum; j++){
row.append('<td>value</td>');
}
}
dialogbox.find('.table_example table').empty().append(tablecontent);
}
});
this.dialogbox
.find('.add_table_options select.table_class')
.change(function(){
dialogbox.find('.table_example table').attr('class','').addClass(jQuery(this).val());
});
this.save = function(){
returnobj['rows'] = this.dialogbox.find('.table_rows').slider('value');
returnobj['cols'] = this.dialogbox.find('.table_cols').slider('value');
returnobj['class'] = this.dialogbox.find('.add_table_options select.table_class').val();
returnobj['data'] = [];
returnobj['types'] = []
for (var i = 0; i<returnobj.rows; i++){
returnobj.data.push([]);
returnobj.types.push([]);
for (var j = 0; j<returnobj.cols; j++){
returnobj.data[i].push('');
returnobj.types[i].push('text');
}
}
this.parent.refreshTable(tnumber);
return true;
}
}
Authortool.prototype.createNumberline = function(returnobj, nlnumber){
/******************************************************
* Tool for creating new numberline
******************************************************/
if (typeof(nlnumber) == 'undefined'){
nlnumber = 0;
}
var tool = this;
var colorSelector = '<select class="color_selector" style="background-color:red;color:white;"><option value="red" style="background-color:red;color:white;">red</option><option value="green" style="background-color:green;color:white;">green</option><option value="blue" style="background-color:blue;color:white;">blue</option><option value="black" style="background-color:black;color:white;">black</option><option value="violet" style="background-color:violet;color:white;">violet</option></select>';
this.openDialog('addnumberline', 'Create new numberline', ['add_nline_caption', 'add_nline_options', 'add_nline_point', 'add_button_bar', 'add_nline_preview']); // Localization
var faceSelector = '<select class="face_selector"><option value="o">o</option><option value="[]">[]</option><option value="+">+</option><option value="x">x</option><option value="^">^</option><option value="v">v</option><option value="<"><</option><option value=">">></option><option value="<>"><></option></select>';
this.nline = new EmathbookNumberline();
var nline = this.nline;
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_nline_caption')
.append('<h2>Numberline caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox
.find('.add_nline_options')
.append('<h2>Options:</h2>\n<div class="nline_range_label">Range: <span class="nline_range">-10 — 10</span></div><div class="nline_range_slider"></div>')
.find('.nline_range_slider').slider({
range: true,
min: -100,
max: 100,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_nline_options').find('.nline_range_label .nline_range').empty().append(ui.values[0] +' — '+ui.values[1]);
}
});
this.dialogbox
.find('.add_nline_point')
.append('<h2>Points:</h2>\n<table class="nline_add_table"><tr>\n<th>name</th>\n<th>type</th>\n<th>value</th>\n<th>stroke color</th>\n<th>fill color</th>\n<th>face</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_point_button">Add point</button><button class="nline_preview">Preview</button></div>')
.find('.add_point_button').click(function(){
jQuery(this).parents('#authordialog_addnumberline').find('.add_nline_point table.nline_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addpointname" title="You can use names with letters and possibly ending with numbers, i.e., of form: [a-zA-Z]+[0-9]*" /></td><td><select class="addpointtype"><option value="point">point</option><option value="glider">glider</option></select></td><td><input type="text" class="addpointvalue" /></td><td class="nlstrokecolor">'+colorSelector+'</td><td class="nlfillcolor">'+colorSelector+'</td><td>'+faceSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('input.addpointname').focusout(function(){
jQuery(this).removeClass('value_error');
if (!jQuery(this).val().match(/^[a-zA-Z]+[0-9]*$/)){
jQuery(this).addClass('value_error');
}
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.nline_preview').click(function(){
var alldata = {"nline": {"nline0":{}}};
var nlinedatas = tool.getNlineData(dialogbox);
dialogbox.find('.add_nline_point table.nline_add_table tr input.addpointname').each(function(){
jQuery(this).parents('tr').eq(0).removeClass('value_error');
if (jQuery(this).val() in nlinedatas[1]){
jQuery(this).parents('tr').eq(0).addClass('value_error');
}
});
alldata.nline.nline0 = nlinedatas[0];
var tiddler;
if (store.tiddlerExists('CreateNumberlinePreview')){
tiddler = store.getTiddler('CreateNumberlinePreview');
} else {
tiddler = store.createTiddler('CreateNumberlinePreview');
}
tiddler.set(tiddler.title,'<<ebooknumberline nline0 savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
wikify('<<tiddler [[CreateNumberlinePreview]]>>', dialogbox.find('.add_nline_preview').empty()[0]);
}).end()
.buttonset();
this.getNlineData = function(elem){
var $elem = jQuery(elem);
var nlobj = new EmathbookNumberline();
jQuery('body').append('<div id="jsxgtestdiv123123" style="display:none;"></div>');
nlobj.create(jQuery('#jsxgtestdiv123123'));
var nlinedata = {
"text": $elem.find('.add_nline_caption .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'),
"startval": $elem.find('.add_nline_options .nline_range_slider').slider('values',0),
"endval": $elem.find('.add_nline_options .nline_range_slider').slider('values',1),
"points": {}
};
var points = {};
$elem.find('.add_nline_point table.nline_add_table tr.datarow').each(function(){
var pointdata = {
"ptype": jQuery(this).find('select.addpointtype').val(),
"xcoord": jQuery(this).find('input.addpointvalue').val(),
"color": jQuery(this).find('.nlstrokecolor select.color_selector').val(),
"fillcolor": jQuery(this).find('.nlfillcolor select.color_selector').val(),
"face": jQuery(this).find('select.face_selector').val().replace('<','<').replace('>','>')
}
if (pointdata.xcoord == parseFloat(pointdata.xcoord)){
pointdata.xcoord = parseFloat(pointdata.xcoord);
}
points[jQuery(this).find('.addpointname').val()] = pointdata;
});
var keepGoing = true;
while (!jQuery.isEmptyObject(points) && keepGoing){
keepGoing = false;
for (var name in points){
if (typeof(points[name].xcoord) == 'number' || !points[name].xcoord.match(/X\([a-zA-Z]+[0-9]*\)/) || (points[name].xcoord.match(/X\([a-zA-Z]+[0-9]*\)/)[0].replace(/X\(([a-zA-Z]+[0-9]*)\)/,'$1') in nlinedata.points)){
nlobj.setdata(nlinedata);
try {
nlinedata.points[name] = points[name];
nlobj.setdata(nlinedata);
nlobj.update();
} catch (e) {
delete nlinedata.points[name];
continue;
}
delete points[name];
keepGoing = true;
}
}
}
jQuery('#jsxgtestdiv123123').remove();
return [nlinedata, points];
}
this.save = function(){
var nldata = this.getNlineData(dialogbox);
if (jQuery.isEmptyObject(nldata[1])){
returnobj['nline'+nlnumber] = nldata[0];
this.parent.refreshNline(nlnumber);
return true;
} else {
dialogbox.find('.nline_preview').click();
return false;
}
}
}
Authortool.prototype.joinImage = function(returnelem){
/******************************************************
* Tool for joining preAttached image to the book
******************************************************/
this.openDialog('joinImage', 'Join image to the book', ['imageSelect','imageCaption','x_size','y_size', 'tag_insert']); // Localization
var tool = this;
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox.find('.x_size').append('<h3>Image width in pixels:</h3><input class="x_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.y_size').append('<h3>Image height in pixels:</h3><input class="y_size_input" type="text"/><b>px</b>');
this.dialogbox.find('.imageCaption').append('<h2>Image caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
// this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="checkbox" id="allImages" /><label for="allImages">All</label></div><div class="imageAddList"></div><div class="imageAddPreview"></div>');
this.dialogbox.find('.imageSelect').append('<h2>Select image:</h2><div class="imageAddControl"><input type="radio" id="onlyLoose" name="radio" checked="checked" /><label for="onlyLoose">Not fixed images</label><input type="radio" id="allPossibles" name="radio" /><label for="allPossibles">All images</label>'/*<input type="radio" id="taggedImages" name="radio" /><label for="taggedImages">Choice tag</label>'*/+'</div><div class="imageAddList"></div><div class="imageAddPreview"></div>').find('.imageAddControl').buttonset();
var selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
function initImageList(imageTiddlers){
tool.dialogbox.find('.imageSelect .imageAddList').html('');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
var imageTiddlersHtmlList="<ul>\n";
for(var i=0;i<imageTiddlers.length;i++){
imageTiddlersHtmlList += '<li imageTiddler="'+imageTiddlers[i].title+'" tiddlerIndex="'+i+'">'+store.getTiddlerText(imageTiddlers[i].title+'##name')+'</li>\n';
}
imageTiddlersHtmlList += '</ul>\n';
tool.dialogbox.find('.imageSelect .imageAddList').append(imageTiddlersHtmlList).find('li').eq(0).addClass('previewed');
if(imageTiddlers.length>0){
wikify('[img['+imageTiddlers[0].title+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
}
tool.dialogbox.find('.imageSelect .imageAddList li').click(function(){
var thisLi = jQuery(this);
var imageTitle = imageTiddlers[thisLi.attr('tiddlerIndex')].title;
thisLi.parent().find('.previewed').removeClass('previewed');
thisLi.addClass('previewed');
tool.dialogbox.find('.imageSelect .imageAddPreview').html('');
wikify('[img['+imageTitle+']]',tool.dialogbox.find('.imageSelect .imageAddPreview')[0]);
});
}
initImageList(selectedImageTiddlers);
this.dialogbox.find('.imageSelect .imageAddControl .ui-button').click(function(event){
switch(jQuery(event.target).text()){
case 'Not fixed images':
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
case 'All images':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
case 'Choice tag':
selectedImageTiddlers = store.getTaggedTiddlers('ebookimage');
break;
default:
selectedImageTiddlers = store.getTaggedTiddlers('looseImage');
break;
}
initImageList(selectedImageTiddlers);
});
this.save = function(){
this.imageTiddler = this.dialogbox.find('.imageSelect .imageAddList li.previewed').attr('imageTiddler');
//returnelem.find('.imagecontainer').append('[img['+this.imageTiddler+']]');
if (!this.imageTiddler){
alert("Please, insert image.");
return false;
}
var content = "!image\n[img["+this.imageTiddler+"]]\n!caption\n"+this.dialogbox.find('.imageCaption .mathquill-editable').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)') +"\n!size-x\n"+this.dialogbox.find('.x_size input.x_size_input').val()+"\n!size-y\n"+this.dialogbox.find('.y_size input.y_size_input').val();
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookgraph tiddlernameplaceholder image>>'
}
this.elementcont.tags.push('ebookgraph_image');
this.elementcont.tags.push('container');
this.elementdata = {
'ebooktitle': '',
'tags': ['bookimage','data'].concat(this.dialogbox.find('input.tags_input').val().split(' ')),
'content': content,
'imageTiddler':this.imageTiddler
}
returnelem.find('.imagedata').append(JSON.stringify(this.elementdata));
wikify('[img['+this.imageTiddler+']]',returnelem.find('.imagecontainer')[0]);
return true;
}
return true;
}
Authortool.prototype.createGraph = function(returnelem){
/******************************************************
* Tool for creating new graphs
******************************************************/
var colorSelector = '<select class="color_selector" style="background-color:#a00;color:white;"><option value="#a00" style="background-color:#a00;color:white;">red</option><option value="#0a0" style="background-color:#0a0;color:white;">green</option><option value="#00a" style="background-color:#00a;color:white;">blue</option><option value="#000" style="background-color:#000;color:white;">black</option><option value="#a0a" style="background-color:#a0a;color:white;">violet</option></select>';
var colorSelector = '<select class="color_selector" style="background-color:red;color:white;"><option value="red" style="background-color:red;color:white;">red</option><option value="green" style="background-color:green;color:white;">green</option><option value="blue" style="background-color:blue;color:white;">blue</option><option value="black" style="background-color:black;color:white;">black</option><option value="violet" style="background-color:violet;color:white;">violet</option></select>';
this.openDialog('addgraphbox', 'Create new graph', ['add_graph_caption', 'add_graph_options', 'add_graphfunc_elem', 'add_graphpoint_elem', 'add_graphslider_elem', 'add_button_bar']); // Localization
var dialogbox = this.dialogbox;
this.dialogbox
.find('.add_graph_caption')
.append('<h2>Graph caption:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox:last').mathquill('textbox');
this.dialogbox
.find('.add_graph_options')
.append('<h2>Options:</h2>\n<div>Axis: <input type="checkbox" class="graph_axis" checked="checked" /><div class="graph_xsize_label">x-range: <span class="graph_xrange">-10 — 10</span></div><div class="graph_xsize"></div><div class="graph_ysize_label">y-range: <span class="graph_yrange">-10 — 10</span></div><div class="graph_ysize"></div></div>')
.find('.graph_xsize').slider({
range: true,
min: -200,
max: 200,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_graph_options').find('.graph_xsize_label .graph_xrange').empty().append(ui.values[0] +' — '+ui.values[1]);
}
}).end()
.find('.graph_ysize').slider({
range: true,
min: -200,
max: 200,
values: [-10,10],
slide: function(event, ui){
jQuery(this).parents('.add_graph_options').find('.graph_ysize_label .graph_yrange').empty().append(ui.values[0] +' — '+ui.values[1]);
}
});
this.dialogbox
.find('.add_graphfunc_elem')
.append('<h2>Functions:</h2>\n<table class="graph_add_table"><tr>\n<th>function</th>\n<th>label</th>\n<th>color</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_graphpoint_elem')
.append('<h2>Points:</h2>\n<table class="graph_add_table"><tr>\n<th>x-coord</th>\n<th>y-coord</th>\n<th>label</th>\n<th>color</th>\n<th></th>\n</tr>\n</table>');
this.dialogbox
.find('.add_graphslider_elem')
.append('<h2>Sliders:</h2>\n<table class="graph_add_table"><tr>\n<th>variable</th>\n<th>min</th>\n<th>max</th>\n<th>default</th>\n<th>step</th>\n<th>label</th>\n</tr>\n</table>');
this.dialogbox
.find('.add_button_bar')
.append('<div class="add_buttonset"><button class="add_function_button">Add function</button><button class="add_point_button">Add point</button><button class="add_slider_button">Add slider</button><button class="remove_slider_button">Remove slider</button><button class="graph_preview">Preview</button></div>')
.find('.add_function_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphfunc_elem table.graph_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addfunction" /></td><td><span class="addlabel mathquill-editable"></span></td><td>'+colorSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.add_point_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphpoint_elem table.graph_add_table tr:last').after('<tr class="datarow"><td><input type="text" class="addpointx" /></td><td><input type="text" class="addpointy" /></td><td><span class="addlabel mathquill-editable"></span></td><td>'+colorSelector+'</td><td class="remove_row"></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('select.color_selector').change(function(){
var color = jQuery(this).val();
jQuery(this).css('background-color',color);
})
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}).end()
.find('.add_slider_button').click(function(){
var svars = [];
jQuery(this).parents('#authordialog_addgraphbox')
.find('.add_graphslider_elem table.graph_add_table td.slidervar')
.each(function(){
var varname = jQuery(this).text();
if (svars.indexOf(varname) == -1){
svars.push(varname);
}
});
var allvars = ['s0','s1','s2','s3','s4'];
var newvar = '';
for (var i = 0; i<allvars.length; i++){
if (svars.indexOf(allvars[i]) == -1){
newvar = allvars[i];
break;
}
}
if (newvar != ''){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphslider_elem table.graph_add_table tr:last').after('<tr class="datarow"><td class="slidervar">'+newvar+'</td><td><input type="text" class="addslidermin" /></td><td><input type="text" class="addslidermax" /></td><td><input type="text" class="addsliderdefault" /></td><td><input type="text" class="addsliderstep" /></td><td><span class="addlabel mathquill-editable"></span></td></tr>')
.next().find('.mathquill-editable').mathquill('editable')
.end().find('td.remove_row').click(function(){
jQuery(this).parents('tr').eq(0).remove();
});
}
}).end()
.find('.remove_slider_button').click(function(){
jQuery(this).parents('#authordialog_addgraphbox').find('.add_graphslider_elem table.graph_add_table tr:last').remove();
}).end()
.find('.graph_preview').click(function(){
var preview = jQuery('<div id="grpreview"></div>');
var alldata = {"graphs":{"graph0":{}}};
alldata.graphs.graph0 = getGraphData(dialogbox);
var tiddler;
if (store.tiddlerExists('createGraphPreview')){
tiddler = store.getTiddler('createGraphPreview');
} else {
tiddler = store.createTiddler('createGraphPreview');
}
tiddler.set(tiddler.title,'<<ebookgraph graph0 functiongraph savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
preview.dialog({
buttons: {
"Close": function(){jQuery(this).dialog("destroy").remove();}
}, //Localization!!
width: 800,
height: 800,
autoOpen: true,
title: 'Graph preview',
modal: true,
close: function(){
jQuery(this).dialog("close").dialog("destroy").remove();
}
});
wikify('<<tiddler [[createGraphPreview]]>>', jQuery('#grpreview')[0]);
}).end()
.buttonset();
var getGraphData = function(elem){
var $elem = jQuery(elem);
var graphdata = {
"caption": $elem.find('.add_graph_caption .mathquill-textbox').mathquill('latex'),
"axis": ($elem.find('.add_graph_options input.graph_axis:checked').length == 1),
"area": [
$elem.find('.add_graph_options .graph_xsize').slider('values',0),
$elem.find('.add_graph_options .graph_ysize').slider('values',1),
$elem.find('.add_graph_options .graph_xsize').slider('values',1),
$elem.find('.add_graph_options .graph_ysize').slider('values',0)
],
"sizex": "500",
"sizey": "auto",
"sliders": [],
"data": []
}
$elem.find('.add_graphfunc_elem table.graph_add_table tr.datarow').each(function(){
var funcdata = {
"type": "function",
"formula_js": jQuery(this).find('input.addfunction').val(),
"color": jQuery(this).find('select.color_selector').val(),
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex'),
"formula_latex": ""
}
graphdata.data.push(funcdata);
});
$elem.find('.add_graphpoint_elem table.graph_add_table tr.datarow').each(function(){
var pointdata = {
"type": "point",
"xcoord": parseFloat(jQuery(this).find('input.addpointx').val()) || 0,
"ycoord": parseFloat(jQuery(this).find('input.addpointy').val()) || 0,
"color": jQuery(this).find('select.color_selector').val(),
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex')
}
pointdata.label += '= (' + pointdata.xcoord + ',' + pointdata.ycoord + ')';
graphdata.data.push(pointdata);
});
$elem.find('.add_graphslider_elem table.graph_add_table tr.datarow').each(function(){
var sliderdata = {
"min": parseFloat(jQuery(this).find('input.addslidermin').val()) || 0,
"max": parseFloat(jQuery(this).find('input.addslidermax').val()) || 0,
"value": parseFloat(jQuery(this).find('input.addsliderdefault').val()) || 0,
"step": parseFloat(jQuery(this).find('input.addsliderstep').val()) || 0,
"label": jQuery(this).find('.mathquill-editable.addlabel').mathquill('latex')
}
graphdata.sliders.push(sliderdata);
});
return graphdata;
}
this.save = function(){
var grdata = getGraphData(this.dialogbox);
if (typeof(returnelem) != 'undefined' && returnelem != null){
jQuery(returnelem).find('.graphdata').append(JSON.stringify(grdata));
var alldata = {"graphs":{"graph0":{}}};
alldata.graphs.graph0 = getGraphData(dialogbox);
var tiddler = store.getTiddler('createGraphPreview');
tiddler.set(tiddler.title,'<<ebookgraph graph0 functiongraph savehere>>\n<data>'+JSON.stringify(alldata)+'</data>');
setTimeout("autoSaveChanges();", 500);
// store.dirty = true;
// if (config.options.chkAutoSave){
// setTimeout("saveChanges();", 500);
// }
wikify('<<tiddler [[createGraphPreview]]>>',jQuery(returnelem).find('.graphcontainer')[0]);
}
return true;
}
}
Authortool.prototype.createImage = function(parenttool){
/******************************************************
* Tool for creating (adding) images
******************************************************/
this.openDialog('addimagebox', 'Add new image', ['add_image_options', 'add_image_elem', 'add_button_bar']); // Localization
wikify('<<attachimage tmpimage_0>>', this.dialogbox.find('.add_image_elem')[0]);
var imagemimes = ['.png','.jpg','.jpeg','.gif'];
if (typeof(this.elemtype) == 'undefined'){
this.elemtype = 'ebookimage';
}
this.save = function(){
/*
* Kupongin tarkistus
*
*/
this.imagedata = {};
this.tiddlerName = this.findFreeTiddler(this.elemtype);
var form = this.dialogbox.find('form')[0];
jQuery(form).find('[name="tiddlertitle"]').val(this.tiddlername);
this.imagedata.src=form.source.value; if (config.browser.isGecko) this.imagedata.src=jQuery(form).find('input#attachFixSource').val();
this.imagedata.when=(new Date()).formatString(config.macros.timeline.dateFormat);
this.imagedata.imagename = form.imagename.value;
this.imagedata.title=form.tiddlertitle.value;
this.imagedata.localpath = './data/images/';
this.imagedata.local = this.imagedata.localpath+this.imagedata.title;
this.imagedata.url = form.URL.value!=form.URL.defaultValue?form.URL.value:"";
this.imagedata.notes = form.notes.value;
this.imagedata.tags = "attachment excludeMissing ebookimage external_file "+form.tags.value;
this.imagedata.useData=form.useData.checked;
this.imagedata.useLocal=form.useLocal.checked;
this.imagedata.useURL=form.useURL.checked;
this.imagedata.mimetype = form.MIMEType.value.length?form.MIMEType.options[form.MIMEType.selectedIndex].text:"";
this.imagedata.author = form.authordata.value;
this.imagedata.source = form.sourcedata.value;
this.imagedata.license = form.licensedata.value;
if (this.imagedata.useData) {
if (this.imagedata.src.length) {
if (!this.imagedata.theLocation){
this.imagedata.theLocation = this.imagedata.src;
} else {
alert('No file defined!'); // Localization
return false;
}
}
}
if (this.imagedata.useURL) {
if (this.imagedata.url.length) {
if (!this.imagedata.theLocation){
this.imagedata.theLocation = this.imagedata.url;
} else {
alert('No url defined!'); // Localization
return false;
}
}
}
if (!(this.imagedata.useData || this.imagedata.useLocal || this.imagedata.useURL) || !(this.imagedata.theLocation)){
alert('No file defined!'); // Localization
return false;
}
if (!this.imagedata.usedata && this.imagedata.mimetype.length > 0 && this.imagedata.theLocation.lastIndexOf('.') != -1){
var extension = this.imagedata.theLocation.substr(this.imagedata.theLocation.lastIndexOf('.')).toLowerCase();
var extlist = form.MIMEType;
for (var i=0; i<extlist.options.length; i++){
if (extlist.options[i].value.indexOf(extension) != -1){
this.imagedata.mimetype = extlist.options[i].text;
extlist.selectedIndex=i;
break;
}
}
}
if (this.imagedata.author.length == 0 || this.imagedata.license.length == 0){
alert('You need to state the author and the license of this image.'); // Localization
return false;
}
if (this.imagedata.source.length == 0 && !confirm('Are you sure, you don\'t want to give the source of the image?')){
// Localization
alert('Attaching of image cancelled.'); // Localization
return false;
}
this.lockType = 'ebookimage';
this.requestLockType();
return false;
}
}
Authortool.prototype.finishImageAuthoring = function(){
/*
* update
* find name
* change name and attach
* send
* remove lock
* end authoring
*/
this.callFifo.push('getUpdates');
this.callFifo.push('saveImage');
this.callFifo.push('sendContent');
this.callFifo.push('removeLockType');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.saveImage = function(){
// TODO: createAttachmentTiddler to Authortool and add "callNext()" to it.
this.tiddlerName = this.findFreeTiddler(this.elemtype);
this.imagedata.title = this.tiddlerName;
this.imagedata.local = this.imagedata.localpath + this.imagedata.title;
this.createAttachmentTiddler(
this.imagedata.src,
this.imagedata.when,
this.imagedata.notes,
this.imagedata.tags,
this.imagedata.title,
this.imagedata.useData,
this.imagedata.useLocal,
this.imagedata.useUrl,
this.imagedata.local,
this.imagedata.url,
this.imagedata.mimetype,
this.imagedata.imagename,
this.imagedata.author,
this.imagedata.source,
this.imagedata.license,
true);
}
Authortool.prototype.createAttachmentTiddler = function (src, when, notes, tags, title, useData, useLocal, useURL, local, url, mimetype, imagename, author, source, license, noshow) {
if (useData) { // encode the data
var imageError = false;
if (!mimetype.length) {
alert('Unknown filetype!'); // Localization
form.MIMEType.selectedIndex=1; form.MIMEType.focus();
imageError = true;
}
var d = config.macros.attachimage.readFile(src);
if (!d) {
alert('Something went wront!\nSorry!'); // Localization
imageError = true;
}
if (d.length > 100000){
alert('Too large file!\nContact Petri.'); // Localization
imageError = true;
}
if (imageError){
this.clearCallFifo();
this.removeLockType();
return false;
}
var encoded = config.macros.attachimage.encodeBase64(d);
}
var usage=(mimetype.substr(0,5)=="image"?'[img[%0]]':'[[%0|%0]]').format([title]);
var theText=config.macros.attachimage.tiddlerFormat.format([
usage, notes.length?notes:'//none//', mimetype,
useLocal?local.replace(/\\/g,'/'):'', useURL?url:'',
useData?('data:'+mimetype+';base64,'+encoded):'' ,
imagename, author, source, license]);
store.saveTiddler(title,title,theText,config.options.txtUserName,new Date(),tags+" looseImage");
this.sendFifo.push({"title": title, "newTiddler": 1});
this.callNext();
return true;
}
Authortool.prototype.tocedit = function(bookid){
var bookdata = DataTiddler.getData(EmathbookPage.config.datatiddler, 'booktocs', {})[bookid];
if (typeof(book) == 'undefined'){
book = {};
}
var book = new Emathbook();
book.init(bookdata);
this.openDialog('tocedit', 'Edit the table of contents', ['toclist']); //Localization!!
jQuery('#authordialog_tocedit .toclist').append(book.tocHtml(false));
jQuery('#authordialog_tocedit .toclist ol.ebooktocsubchap li')
.not('ol li ol li ol li')
.each(function(){
if (jQuery(this).find('ol').length == 0){
jQuery(this).append('<ol class="ebooktocsubchap" style="min-height: 5px; min-width: 5px;"></ol>\n');
}
});
jQuery('#authordialog_tocedit .toclist ol.ebooktocsubchap').sortable({
placeholder: 'ui-state-highlight',
helper: 'clone',
forcePlaceholderSize: true
}).disableSelection();
jQuery('#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap').sortable(
'option', 'connectWith', '#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap'
);
jQuery('#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap > li > ol.ebooktocsubchap').sortable(
'option', 'connectWith', '#authordialog_tocedit .toclist .ebooktoc > ol.ebooktocsubchap > li > ol.ebooktocsubchap > li > ol.ebooktocsubchap'
);
}
Authortool.prototype.createPrerequisites = function(){
/******************************************************
* Tool for creating a new prerequisitesbox
* TODO: combine more with createExample
******************************************************/
var requisite = '<li><span class="mathquill-textbox"></span></li>';
this.tiddlerName = this.findFreeTiddler('prerequisites');
this.openDialog('addprerequisites', 'Create new prerequisites list', ['add_prerequisites_head', 'tag_insert','prerequisites_list', 'add_prerequisites_elem']); // Localization
this.dialogbox
.find('.add_prerequisites_head')
.append('<h2>Prerequisitesbox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.prerequisites_list')
.append('<h2>Prerequisites:</h2><ul>'+requisite+'</ul>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox
.find('.add_prerequisites_elem')
.append('<button class="add_prerequisites_button">Add prerequisite</button>')
.find('.add_prerequisites_button').click(function(){
jQuery(this).parents('#authordialog_addprerequisites').find('.prerequisites_list ul').append(requisite)
.find('.mathquill-textbox:last').mathquill('textbox');
}).button();
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] prerequisites>>'
}
this.elementcont.tags.push('prerequisites');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['prerequisites','data'],
'content': '',
'data': {}
}
var disHead = this.dialogbox.find('.add_prerequisites_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '!' + (disHead=='' ? 'Esitiedot': disHead ) + '\n';
var elements = this.dialogbox.find('.prerequisites_list ul>li');
for (var i = 0;i<elements.length;i++){
var list_question = elements.eq(i).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '*'+list_question+'\n';
};
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createDiscussion = function(){
/******************************************************
* Tool for creating a new discussionbox
* TODO: combine more with createExample
******************************************************/
var question = '<li class="question"><span class="mathquill-textbox"></span><ul></ul><button class="add_subquestion">Sub</button></li>';
var subquestion = '<li class="subquestion"><span class="mathquill-textbox"></span></li>';
this.tiddlerName = this.findFreeTiddler('discussion');
this.openDialog('adddiscussion', 'Create new discussion', ['add_discussion_head', 'tag_insert', 'add_prediscussion_elem', 'add_prebutton_bar','discussion_list', 'add_discussion_elem', 'add_postdiscussion_elem', 'add_postbutton_bar']); // Localization
this.dialogbox
.find('.add_discussion_head')
.append('<h2>Discussionbox header:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_prediscussion_elem')
.append('<h2>Before questions:</h2>');
this.dialogbox
.find('.discussion_list')
.append('<h2>Discussion questions:</h2><ol>'+question+'</ol>')
.find('.mathquill-textbox').mathquill('textbox')
.end()
.find('.add_subquestion')
.button().click(function(){jQuery(this).parent().find('ul').append(subquestion).find('.mathquill-textbox').mathquill('textbox');});
this.dialogbox
.find('.add_postdiscussion_elem')
.append('<h2>After questions:</h2>');
this.dialogbox
.find('.add_prebutton_bar')
.append('<div class="add_prebuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_image_button">Image</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem').append('<div><textarea class="discussion_elem add_discussion_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem').append('<div class="mathdisplaystyle"><span class="discussion_elem add_discussion_formula mathquill-editable"></span></div>')
.find('.mathquill-editable').mathquill('editable')
.end()
.find('.add_subquestion').button();;
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem');
addelem.append('<div><div class="discussion_elem add_discussion_graph" style="border:1px solid black;"><div class="graphcontainer"></div><span style="display:none;" class="graphdata"></span><div></div>');
addelem = addelem.find('.add_discussion_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_prediscussion_elem');
addelem.append('<div><div class="discussion_elem add_discussion_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_discussion_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
this.dialogbox
.find('.add_discussion_elem')
.append('<button class="add_discussion_button">Add discussion question</button>')
.find('.add_discussion_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.discussion_list ol').append(question)
.find('.mathquill-textbox:last').mathquill('textbox')
.end()
.find('.add_subquestion:last')
.button().click(function(){jQuery(this).parent().find('ul').append(subquestion).find('.mathquill-textbox:last').mathquill('textbox');});
}).button();
this.dialogbox
.find('.add_postbutton_bar')
.append('<div class="add_postbuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_image_button">Image</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem').append('<div><textarea class="discussion_elem add_discussion_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem').append('<div class="mathdisplaystyle"><span class="discussion_elem add_discussion_formula mathquill-editable"></span></div>').find('.mathquill-editable').mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem')
addelem.append('<div><div class="discussion_elem add_discussion_graph" style="border:1px solid black;"><div class="graphcontainer"></div><span style="display:none;" class="graphdata"></span><div></div>');
addelem = addelem.find('.add_discussion_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_adddiscussion').find('.add_postdiscussion_elem');
addelem.append('<div><div class="discussion_elem add_discussion_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_discussion_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.buttonset();
this.save = function(){
this.elementcont = {
'ebooktitle': '',
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '<<ebookbox [[tiddlernameplaceholder_data]] discussion>>'
}
this.elementcont.tags.push('discussion');
this.elementcont.tags.push('container');
this.elementcont.tags.push('notFixed'); // TODO: remove this
this.elementdata = {
'ebooktitle': '',
'tags': ['discussion','data'],
'content': '',
'data': {}
}
var disHead = this.dialogbox.find('.add_discussion_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
this.elementdata.content += '!' + (disHead=='' ? 'Pohdintaa': disHead ) + '\n';
var graphcount = 0;
var imagecount = 0;
var discussionderiv_number = 0;
var elements = this.dialogbox.find('.add_prediscussion_elem .discussion_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_discussion_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_discussion_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_discussion_deriv')){
this.elementdata.content += '<<qedderiv discussionsd'+discussionderiv_number+' savehere>>\n';
discussionderiv_number++;
} else if (elements.eq(i).hasClass('add_discussion_graph')){
this.elementdata.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementdata.data.graphs) == 'undefined'){
this.elementdata.data.graphs = {};
}
this.elementdata.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (elements.eq(i).hasClass('add_discussion_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
elements = this.dialogbox.find('.discussion_list ol>li');
for (var i = 0;i<elements.length;i++){
var list_question = elements.eq(i).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
var subquestion_list =elements.eq(i).children('ul').find('li.subquestion');
this.elementdata.content += '#'+list_question+'\n';
for (var j=0;j<subquestion_list.length;j++){
var list_subquestion = subquestion_list.eq(j).children('span').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
if (list_subquestion != ''){
this.elementdata.content += '##'+list_subquestion+'\n';
}
}
};
elements = this.dialogbox.find('.add_postdiscussion_elem .discussion_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_discussion_text')){
this.elementdata.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_discussion_formula')){
this.elementdata.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_discussion_deriv')){
this.elementdata.content += '<<qedderiv discussionsd'+discussionderiv_number+' savehere>>\n';
discussionderiv_number++;
} else if (elements.eq(i).hasClass('add_discussion_graph')){
this.elementdata.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementdata.data.graphs) == 'undefined'){
this.elementdata.data.graphs = {};
}
this.elementdata.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (elements.eq(i).hasClass('add_discussion_image')){
if (imagecount == 0){
this.elementdata.imagedata = [];
}
this.elementdata.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.elementdata.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
this.finishAuthoring();
return true;
}
return this.tiddlerName;
}
Authortool.prototype.createOtherassignment = function(){
/******************************************************
* Tool for creating a new otherassignmentbox
* TODO:
******************************************************/
testilogit.tool = this;
var tool = this;
var question = '<li class="question"><span class="mathquill-textbox"></span><ul></ul><button class="add_subquestion">Sub</button></li>';
var subquestion = '<li class="subquestion"><span class="mathquill-textbox"></span></li>';
var derivations = 0;
this.tiddlerName = this.findFreeTiddler('otherAssignment');
this.openDialog('addotherassignment', 'Create new assignment', ['add_otherassignment_head', 'tag_insert', 'add_preotherassignment_elem', 'add_prebutton_bar','otherassignment_list', 'add_otherassignment_elem', 'add_postotherassignment_elem', 'add_postbutton_bar']); // Localization
this.dialogbox
.find('.add_otherassignment_head')
.append('<h2>Additional title:</h2><span class="mathquill-textbox"></span>')
.find('.mathquill-textbox').mathquill('textbox');
this.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
this.dialogbox
.find('.add_preotherassignment_elem')
.append('<h2>Before questions:</h2>');
this.dialogbox
.find('.otherassignment_list')
.append('<h2>otherassignment questions:</h2><ol></ol>');
this.dialogbox
.find('.add_postotherassignment_elem')
.append('<h2>After questions:</h2>');
this.dialogbox
.find('.add_prebutton_bar')
.append('<div class="add_prebuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button><button class="add_table_button">Table</button><button class="add_nline_button">Numberline</button><button class="add_image_button">Image</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem').append('<div><textarea class="otherassignment_elem add_otherassignment_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem').append('<div class="mathdisplaystyle"><span class="otherassignment_elem add_otherassignment_formula mathquill-editable"></span></div>')
.find('.mathquill-editable').mathquill('editable')
.end()
.find('.add_subquestion').button();;
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem')
addelem.append('<div><div class="otherassignment_elem add_otherassignment_graph" style="border:1px solid black;"><div class="graphcontainer">Here will be a graph</div><span style="display:none;" class="graphdata"></span><div></div>');
addelem = addelem.find('.add_otherassignment_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.find('.add_image_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
addelem.append('<div><div class="otherassignment_elem add_otherassignment_image" style="border:1px solid black;"><div class="imagecontainer"></div><span style="display:none;" class="imagedata"></span></div></div>');
addelem = addelem.find('.add_otherassignment_image:last');
var imagetool = new Authortool();
imagetool.joinImage(addelem);
}).end()
.find('.add_table_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var tablenum = jQuery(this).parents('#authordialog_addotherassignment').find('.add_table_content').length;
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.append('<div class="table_container"><div class="otherassignment_elem add_table_content extable_'+tablenum+'" assignmenttable="'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tparent = jQuery(this).parents('.table_container').find('.add_table_content').eq(0);
var tablenumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tablenumber = parseInt(tablenumber);
// var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
}).end()
.find('.add_nline_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_preotherassignment_elem');
var nlnum = addelem.find('.add_nline_content').length;
if (nlnum == 0){
tool.nlines = {"nline0":{}};
} else {
tool.nlines['nline'+nlnum] = {};
}
addelem.append('<div><div class="otherassignment_elem add_nline_content" style="border:1px solid black;"><div class="nlinecontainer" id="nlinecontainer_'+nlnum+'"></div></div></div>');
var nlinetool = new Authortool();
nlinetool.parent = tool;
nlinetool.createNumberline(tool.nlines, nlnum);
}).end()
.buttonset();
this.dialogbox
.find('.add_otherassignment_elem')
.append('Add Question: <select class="assignmentselection">\n <option value="0" selected="selected">Select assignment type</option>\n <option value="1">Plain Text</option>\n <option value="2">Multichoise</option>\n <option value="3">Shortanswer</option>\n <option value="5">SDshuffle</option>\n <option value="6">FillSD</option>\n <option value="7">FillTable</option>\n</select> ')
.find('.assignmentselection').change(function(){
switch(jQuery(this).val())
{
case "1":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="1">Question text:<span class="questionPlain mathquill-editable"></span><ol class="subotherassignment_list"></ol><hr><span class="addSubQ">Add Subquestion: <select class="subassignmentselection">\n <option value="0" selected="selected">Select assignment type</option>\n <option value="2">Multichoise</option>\n <option value="3">Shortanswer</option>\n <option value="5">SDshuffle</option>\n <option value="6">FillSD</option>\n <option value="7">FillTable</option>\n</select></span></li>')
.find('.mathquill-editable:last').mathquill('textbox').focus()
.end()
.find('.subassignmentselection').change(function(){
var addplace = jQuery(this).parent().parent().find('ol.subotherassignment_list')
switch(jQuery(this).val())
{
case "2":
addplace.append('<li class="subquestion" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable"></span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable"></span></li><li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li></ul><hr><button class="addMultiwrong">Add incorrect</button></li>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end()
.find('.addMultiwrong:last').button().click(function(){
jQuery(this).parent().find('ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li>').find('.mathquill-editable:last').mathquill('textbox');
});
break;
case "3":
addplace.append('<li class="subquestion" quetionType="3">Shortanswer question:<span class="questionShortA mathquill-editable"></span></li>')
.find('span.questionShortA:last').mathquill('textbox').focus();
break;
case "5":
var questionPlace = addplace.append('<li class="subquestion" quetionType="5">Structured derivation to shuffle:<span class="questionSDshuffle" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"]')[0]);
derivations++;
break;
case "6":
var questionPlace = addplace.append('<li class="subquestion" quetionType="6">Partly filled structured derivation:<span class="questionSDfill" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"]')[0]);
derivations++;
break;
case "7":
var tablenum = addplace.parents('.dialogelement').parent().find('.add_table_content').length;
var questionPlace = addplace.append('<li class="subquestion" quetionType="7">Partly filled table:<span class="questionTablefill" assignmenttable="'+tablenum+'"></span></li>');
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addplace.find('.questionTablefill[assignmenttable="'+tablenum+'"]').append('<div class="table_container"><div class="add_table_content assignmenttable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addplace.find('.table_container:last a.edittypebutton').button().click(function(){
var tparent = jQuery(this).parents('.table_container').find('.add_table_content').eq(0);
var tablenumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tablenumber = parseInt(tablenumber);
// var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addplace.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addplace = addplace.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
break;
default:
alert("Try other");
}
jQuery(this).find('[selected="selected"]').removeAttr('selected').end().find('option').eq(0).attr('selected','selected');
});
break;
case "2":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="2">Multichoise question:<span class="questionMulti mathquill-editable"></span><ul class="multichoise"><li class="correct"><span class="correctchoice mathquill-editable"></span></li><li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li></ul><hr><button class="addMultiwrong">Add incorrect</button></li>')
.find('span.questionMulti:last').mathquill('textbox').focus()
.end()
.find('ul.multichoise:last').find('.mathquill-editable').mathquill('textbox')
.end().end()
.find('.addMultiwrong:last').button().click(function(){
jQuery(this).parent().find('ul.multichoise').append('<li class="incorrect"><span class="incorrectchoise mathquill-editable"></span></li>').find('.mathquill-editable:last').mathquill('textbox');
});
break;
case "3":
jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="3">Shortanswer question:<span class="questionShortA mathquill-editable"></span></li>')
.find('span.questionShortA:last').mathquill('editable').focus();
break;
case "5":
var questionPlace = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="5">Structured derivation to shuffle:<span class="questionSDshuffle" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"]')[0]);
questionPlace.find('.questionSDshuffle[assignmentDeriv="'+derivations+'"] .command_qededit').click();
derivations++;
break;
case "6":
var questionPlace = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol').append('<li class="question" quetionType="6">Partly filled structured derivation:<span class="questionSDfill" assignmentDeriv="'+derivations+'"></span></li>');
wikify('<<qedderiv assignmentsd'+derivations+'>>', questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"]')[0]);
questionPlace.find('.questionSDfill[assignmentDeriv="'+derivations+'"] .command_qededit').click();
derivations++;
break;
case "7":
var addelem = jQuery(this).parents('#authordialog_addotherassignment')
.find('.otherassignment_list>ol');
var tablenum = addelem.parents('.dialogelement').parent().find('.add_table_content').length;
var questionPlace = addelem.append('<li class="question" quetionType="7">Partly filled table:<span class="questionTablefill" assignmenttable="'+tablenum+'"></span></li>');
if (tablenum == 0){
tool.tables = {"table0":{"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""}};
} else {
tool.tables['table'+tablenum] = {"rows": 1, "cols": 1, "class": "", "data":[['']], "caption": ""};
}
addelem.find('.questionTablefill[assignmenttable="'+tablenum+'"]').append('<div class="table_container"><div class="add_table_content assignmenttable_'+tablenum+'"><table><tbody></tbody></table></div><div class="add_table_caption"><strong>Caption:</strong><span class="tablecaption mathquill-textbox"></span></div><div class="add_table_edittypes"><a href="javascript:;" class="edittypebutton"><span class="edittypes">Edit cell types</span><span class="editvalues">Edit cell values</span></a></div></div>');
addelem.find('.table_container:last a.edittypebutton').button().click(function(){
var tparent = jQuery(this).parents('.table_container').find('.add_table_content').eq(0);
var tablenumber = tparent.attr('class').replace(/^.*(extable_|assignmenttable_)([0-9]+).*$/,"$2");
tablenumber = parseInt(tablenumber);
// var tablenumber = tool.dialogbox.find('.add_table_content').index(jQuery(this).parents('.table_container').find('.add_table_content'));
if (jQuery(this).parent().hasClass('edittypes')){
jQuery(this).parent().removeClass('edittypes');
tool.refreshTable(tablenumber);
} else {
jQuery(this).parent().addClass('edittypes');
tool.refreshTableTypes(tablenumber);
}
});
var captext = addelem.find('.table_container:last .add_table_caption .tablecaption.mathquill-textbox');
captext.mathquill('textbox');
captext.focusout(function(){
var tablenum = tool.dialogbox.find('.table_container .tablecaption').index(jQuery(this));
tool.tables['table'+tablenum].caption = jQuery(this).mathquill('latex');
});
addelem = addelem.find('.add_table_content:last');
var tabletool = new Authortool();
tabletool.parent = tool;
tabletool.createTable(tool.tables['table'+tablenum], tablenum);
break;
default:
}
jQuery(this).find('[selected="selected"]').removeAttr('selected').end().find('option').eq(0).attr('selected','selected');
});
this.dialogbox
.find('.add_postbutton_bar')
.append('<div class="add_postbuttonset"><button class="add_text_button">Add text element</button><button class="add_displayform_button">Add displaystyle formula</button><button class="add_graph_button">Add graph</button></div>') //<button class="add_derivation_button">Add Structured derivation</button>
.find('.add_text_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem').append('<div><textarea class="otherassignment_elem add_otherassignment_text"></textarea></div>');
}).end()
.find('.add_displayform_button').click(function(){
jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem').append('<div class="mathdisplaystyle"><span class="otherassignment_elem add_otherassignment_formula mathquill-editable"></span></div>').find('.mathquill-editable').mathquill('editable');
}).end()
.find('.add_graph_button').click(function(){
var addelem = jQuery(this).parents('#authordialog_addotherassignment').find('.add_postotherassignment_elem')
addelem.append('<div><div class="otherassignment_elem add_otherassignment_graph" style="border:1px solid black;"><div class="graphcontainer">Here will be a graph</div><span style="display:none;" class="graphdata"></span><div></div>');
addelem = addelem.find('.add_otherassignment_graph:last');
var tool = new Authortool();
tool.createGraph(addelem);
}).end()
.buttonset();
this.save = function(){
var disHead = this.dialogbox.find('.add_otherassignment_head .mathquill-textbox').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)');
var placeholderNro=0;
this.elementcont = {
'ebooktitle': (disHead=='' ? '': disHead ),
'tags': this.dialogbox.find('input.tags_input').val().split(' '),
'content': '',
'data': {}
}
this.elementcont.tags.push('otherassignment');
this.elementcont.tags.push('container');
this.elementdata = [];
var graphcount = 0;
var tablecount = 0;
var nlinecount = 0;
var imagecount = 0;
var otherassignmentderiv_number = 0;
var elements = this.dialogbox.find('.add_preotherassignment_elem .otherassignment_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_otherassignment_text')){
this.elementcont.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_otherassignment_formula')){
this.elementcont.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_otherassignment_deriv')){
this.elementcont.content += '<<qedderiv otherassignmentsd'+otherassignmentderiv_number+' savehere>>\n';
otherassignmentderiv_number++;
} else if (elements.eq(i).hasClass('add_otherassignment_graph')){
this.elementcont.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementcont.data.graphs) == 'undefined'){
this.elementcont.data.graphs = {};
}
this.elementcont.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
} else if (elements.eq(i).hasClass('add_table_content')){
this.elementcont.content += '<<ebooktable table'+tablecount+' '+this.tables['table'+tablecount].class+' savehere>>\n';
if (tablecount == 0){
this.elementcont.data.table = this.tables;
}
tablecount++;
} else if (elements.eq(i).hasClass('add_nline_content')){
this.elementcont.content += '<<ebooknumberline nline'+nlinecount+' savehere>>\n';
if (nlinecount == 0){
this.elementcont.data.nline = this.nlines;
}
nlinecount++;
} else if (elements.eq(i).hasClass('add_otherassignment_image')){
if (imagecount == 0){
this.elementcont.imagedata = [];
}
this.elementcont.content += '<<ebookgraph imageplaceholder'+imagecount+' image>>\n';
this.elementcont.imagedata.push(JSON.parse(elements.eq(i).find('.imagedata').text()));
imagecount++;
}
}
elements = this.dialogbox.find('.otherassignment_list ol>li.question');
for (var i = 0;i<elements.length;i++){
var otherQuestion = new EmathbookAssignnment("otherass_"+placeholderNro,elements.eq(i).attr('quetionType'));
this.elementcont.content += '# <<showAssignment otherass_'+placeholderNro+'>>\n';
placeholderNro++;
switch(elements.eq(i).attr('quetionType')){
case "1":
otherQuestion.setText(elements.eq(i).children('span.questionPlain').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var subquestion_list =elements.eq(i).children('ol').find('li.subquestion');
for (var j=0;j<subquestion_list.length;j++){
var othersubQuestion = new EmathbookAssignnment("otherass_"+placeholderNro,subquestion_list.eq(j).attr('quetionType'));
switch(subquestion_list.eq(j).attr('quetionType')){
case "2":
othersubQuestion.setText(subquestion_list.eq(j).children('span.questionMulti').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
othersubQuestion.setData("correct",subquestion_list.eq(j).find('ul li.correct span.correctchoice').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var $multiWrongs = subquestion_list.eq(j).find('ul li.incorrect span.incorrectchoise');
var multiWronglist = [];
for (var k=0;k<$multiWrongs.length;k++){
multiWronglist.push($multiWrongs.eq(k).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
}
othersubQuestion.setData("wrong", multiWronglist);
break;
case "3":
var SAquestion = subquestion_list.eq(j).children('.questionShortA').mathquill('latex');
var solutionsSpans= subquestion_list.eq(j).find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var SAsolution = solutionsSpans.eq(k).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
othersubQuestion.setText(SAquestion);
if (hasSolutions){othersubQuestion.setData("correct", SAsolutions);}
break;
case "5":
othersubQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{})
othersubQuestion.setData("derivations", {"assignmentsd0": shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDshuffle').attr('assignmentDeriv')]});
break;
case "6":
othersubQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
var strShuffleDerivation = shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDfill').attr('assignmentDeriv')] ? JSON.stringify(shuffleDerivation['assignmentsd'+subquestion_list.eq(j).children('.questionSDfill').attr('assignmentDeriv')]) : JSON.stringify({"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"","virgin":false}],"relation":[],"motivation":[],"check":""});
var fillMotivations = elements.eq(i).find('table.sdtable td.motivation span.solution');
var fillTerms = elements.eq(i).find('table.sdtable td.term span.solution');
var fillRelations = elements.eq(i).find('table.sdtable td.relation span.solution');
var hasSolutions = true;
var solutionsSpans = jQuery.merge(fillMotivations,fillTerms);
solutionsSpans = jQuery.merge(solutionsSpans,fillRelations);
var FillSDsolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var FillSDsolution = solutionsSpans.eq(k).mathquill('latex');
FillSDsolution = (FillSDsolution.charAt(FillSDsolution.length-1)==" "? FillSDsolution.substring(0,FillSDsolution.length-1): FillSDsolution);
FillSDsolution = FillSDsolution.replace(/\ ([\+\-\}])/g,'$1');
FillSDsolutions.push(FillSDsolution);
if (FillSDsolution==""){ hasSolutions = false;}
strShuffleDerivation = strShuffleDerivation.replace('\\\\solution{'+FillSDsolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
if (hasSolutions){othersubQuestion.setData("correct", FillSDsolutions);}
othersubQuestion.setData("derivations", {"assignmentsd0": JSON.parse(strShuffleDerivation)});
break;
case "7":
var tablenro = subquestion_list.eq(j).children('.questionTablefill').attr('assignmenttable');
var FillTableData = JSON.stringify(tool.tables['table'+tablenro].data);
var solutionsSpans= subquestion_list.eq(j).find('.solution');
var hasSolutions = true;
var FillTablesolutions = [];
for(var k=0; k<solutionsSpans.length;k++){
var FillTablesolution = solutionsSpans.eq(k).mathquill('latex');
FillTablesolution = (FillTablesolution.charAt(FillTablesolution.length-1)==" "? FillTablesolution.substring(0,FillTablesolution.length-1): FillTablesolution);
FillTablesolution=FillTablesolution.replace(/\ ([\+\-\}])/g,'$1');
FillTablesolutions.push(FillTablesolution);
if (FillTablesolution==""){ hasSolutions = false;}
FillTableData = FillTableData.replace('\\\\solution{'+FillTablesolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
tool.tables['table'+tablenro].data = JSON.parse(FillTableData);
if (hasSolutions){othersubQuestion.setData("correct", FillTablesolutions);}
othersubQuestion.setText('<<ebooktable assignmentTable0 '+tool.tables['table'+tablenro].class+' savehere>>');
othersubQuestion.setData("table", {"assignmentTable0":tool.tables['table'+tablenro]});
break;
default:
}
this.elementcont.content += '## <<showAssignment otherass_'+placeholderNro+'>>\n';
placeholderNro++;
this.elementdata.push(othersubQuestion);
}
break;
case "2":
otherQuestion.setText(elements.eq(i).children('span.questionMulti').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
otherQuestion.setData("correct",elements.eq(i).find('ul li.correct span.correctchoice').mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
var $multiWrongs = elements.eq(i).find('ul li.incorrect span.incorrectchoise');
var multiWronglist = [];
for (var j=0;j<$multiWrongs.length;j++){
multiWronglist.push($multiWrongs.eq(j).mathquill('latex').replace(/\$([^\$]*)\$/g,'\\($1\\)'));
}
otherQuestion.setData("wrong", multiWronglist);
break;
case "3":
var SAquestion = elements.eq(i).children('.questionShortA').mathquill('latex');
var solutionsSpans= elements.eq(i).find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var SAsolution = solutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
otherQuestion.setText('\\('+SAquestion+'\\)');
if (hasSolutions){otherQuestion.setData("correct", SAsolutions);}
break;
case "5":
otherQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
otherQuestion.setData("derivations", {"assignmentsd0": shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDshuffle').attr('assignmentDeriv')]});
break;
case "6":
otherQuestion.setText('<<qedderiv assignmentsd0 savehere>>');
var shuffleDerivation = DataTiddler.getData('QedDerivationsData','derivations',{});
var strShuffleDerivation = shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDfill').attr('assignmentDeriv')] ? JSON.stringify(shuffleDerivation['assignmentsd'+elements.eq(i).children('.questionSDfill').attr('assignmentDeriv')]) : JSON.stringify({"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":"","virgin":false}],"relation":[],"motivation":[],"check":""});
var fillMotivations = elements.eq(i).find('table.sdtable td.motivation span.solution');
var fillTerms = elements.eq(i).find('table.sdtable td.term span.solution');
var fillRelations = elements.eq(i).find('table.sdtable td.relation span.solution');
var hasSolutions = true;
var solutionsSpans = jQuery.merge(fillMotivations,fillTerms);
solutionsSpans = jQuery.merge(solutionsSpans,fillRelations);
var FillSDsolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var FillSDsolution = solutionsSpans.eq(j).mathquill('latex');
FillSDsolution = (FillSDsolution.charAt(FillSDsolution.length-1)==" "? FillSDsolution.substring(0,FillSDsolution.length-1): FillSDsolution);
FillSDsolution = FillSDsolution.replace(/\ ([\+\-\}])/g,'$1');
FillSDsolutions.push(FillSDsolution);
if (FillSDsolution==""){ hasSolutions = false;}
strShuffleDerivation = strShuffleDerivation.replace('\\\\solution{'+FillSDsolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
if (hasSolutions){otherQuestion.setData("correct", FillSDsolutions);}
otherQuestion.setData("derivations", {"assignmentsd0": JSON.parse(strShuffleDerivation)});
break;
case "7":
var tablenro = elements.eq(i).children('.questionTablefill').attr('assignmenttable');
var FillTableData = JSON.stringify(tool.tables['table'+tablenro].data);
var solutionsSpans= elements.eq(i).find('.solution');
var hasSolutions = true;
var FillTablesolutions = [];
for(var j=0; j<solutionsSpans.length;j++){
var FillTablesolution = solutionsSpans.eq(j).mathquill('latex');
FillTablesolution = (FillTablesolution.charAt(FillTablesolution.length-1)==" "? FillTablesolution.substring(0,FillTablesolution.length-1): FillTablesolution);
FillTablesolution=FillTablesolution.replace(/\ ([\+\-\}])/g,'$1');
FillTablesolutions.push(FillTablesolution);
if (FillTablesolution==""){ hasSolutions = false;}
FillTableData = FillTableData.replace('\\\\solution{'+FillTablesolution.replace(/\\/g,'\\\\')+'}','\\\\solution{\\\\editable{}}');
}
tool.tables['table'+tablenro].data = JSON.parse(FillTableData);
if (hasSolutions){otherQuestion.setData("correct", FillTablesolutions);}
otherQuestion.setText('<<ebooktable assignmentTable0 '+tool.tables['table'+tablenro].class+' savehere>>');
otherQuestion.setData("table", {"assignmentTable0":tool.tables['table'+tablenro]});
break;
default:
}
this.elementdata.push(otherQuestion);
};
elements = this.dialogbox.find('.add_postotherassignment_elem .otherassignment_elem');
for (var i = 0; i<elements.length; i++){
if (elements.eq(i).hasClass('add_otherassignment_text')){
this.elementcont.content += elements.eq(i).val() + '\n';
} else if (elements.eq(i).hasClass('add_otherassignment_formula')){
this.elementcont.content += '\\['+elements.eq(i).mathquill('latex')+'\\]\n';
} else if (elements.eq(i).hasClass('add_otherassignment_deriv')){
this.elementcont.content += '<<qedderiv otherassignmentsd'+otherassignmentderiv_number+' savehere>>\n';
otherassignmentderiv_number++;
} else if (elements.eq(i).hasClass('add_otherassignment_graph')){
this.elementcont.content += '<<ebookgraph graph'+graphcount+' functiongraph savehere>>\n';
if (typeof(this.elementcont.data.graphs) == 'undefined'){
this.elementcont.data.graphs = {};
}
this.elementcont.data.graphs['graph'+graphcount] = JSON.parse(elements.eq(i).find('span.graphdata').text());
graphcount++;
}
}
this.requestLockType();
return false;
}
return this.tiddlerName;
}
Authortool.prototype.saveNewElement = function(){
/******************************************************
* Save tiddlers of new element and push to sendFifo.
******************************************************/
switch(this.elemtype){
case 'joinimage':
this.imageTiddlerName = this.findFreeTiddler('image');
this.tiddlerName = this.findFreeTiddler('graphelement');
this.elementcont.content = this.elementcont.content.replace('tiddlernameplaceholder', this.imageTiddlerName);
this.saveTiddler(this.tiddlerName, this.elementcont.content, this.elementcont.tags, this.elementcont.ebooktitle);
this.saveTiddler(this.imageTiddlerName, this.elementdata.content, this.elementdata.tags, this.elementdata.ebooktitle);
store.getTiddler(this.imageTiddler).tags.remove('looseImage');
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.sendFifo.push({"title": this.imageTiddlerName, "newTiddler": 1});
break;
default:
if(typeof(this.elementdata.imagedata) != 'undefined'){
for(var i=0;i<this.elementdata.imagedata.length;i++){
var imageContainer = this.findFreeTiddler('image');
this.elementdata.content = this.elementdata.content.replace("imageplaceholder"+i,imageContainer);
this.sendFifo.push({"title": this.saveTiddler(imageContainer, this.elementdata.imagedata[i].content, this.elementdata.imagedata[i].tags, this.elementdata.imagedata[i].ebooktitle), "newTiddler": 1});
store.getTiddler(this.elementdata.imagedata[i].imageTiddler).tags.remove('looseImage');
}
}
this.tiddlerName = this.findFreeTiddler(this.elemtype);
this.elementcont.content = this.elementcont.content.replace('tiddlernameplaceholder', this.tiddlerName);
this.saveTiddler(this.tiddlerName, this.elementcont.content, this.elementcont.tags, this.elementcont.ebooktitle);
this.saveTiddler(this.tiddlerName+'_data', this.elementdata.content, this.elementdata.tags, this.elementdata.ebooktitle);
for (datakey in this.elementdata.data){
DataTiddler.setData(this.tiddlerName+'_data', datakey, this.elementdata.data[datakey], {});
}
this.sendFifo.push({"title": this.tiddlerName, "newTiddler": 1});
this.sendFifo.push({"title": this.tiddlerName+'_data', "newTiddler": 1});
break;
}
this.addInTiddler();
this.callNext();
}
Authortool.prototype.endAuthoring = function(){
/******************************************************
* End authoring (close dialog, refresh,...)
******************************************************/
if (typeof(this.dialogbox) != 'undefined'){
this.dialogbox.dialog('destroy').remove();
}
refreshElements(jQuery('#pageOneWrapper')[0]);
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
alert('Done!'); //Localization
}
Authortool.prototype.startAuthoring = function(action){
/******************************************************
* Start adding/editing/removing element in chapter/section/subsection
******************************************************/
if (action == undefined){
return false;
}
this.callFifo.push('getUpdates');
switch (action){
case 'edit':
this.callFifo.push('requestLock');
this.callFifo.push('editElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
break;
case 'remove':
this.callFifo.push('requestLock');
this.callFifo.push('removeElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('getUpdates');
break;
case 'addebooktable':
this.callFifo.push('requestLock');
this.elemtype = 'tableelement';
this.callFifo.push('addElement');
break;
case 'addexamplesd':
this.callFifo.push('requestLock');
this.elemtype = 'examplesd';
this.callFifo.push('addElement');
break;
case 'addexample':
this.callFifo.push('requestLock');
this.elemtype = 'examplebox';
this.callFifo.push('addElement');
break;
case 'addtheory':
this.callFifo.push('requestLock');
this.elemtype = 'theorybox';
this.callFifo.push('addElement');
break;
case 'addtext':
this.callFifo.push('requestLock');
this.elemtype = 'textelement';
this.callFifo.push('addElement');
break;
case 'adddiscussion':
this.callFifo.push('requestLock');
this.elemtype = 'discussion';
this.callFifo.push('addElement');
break;
case 'addprerequisites':
this.callFifo.push('requestLock');
this.elemtype = 'prerequisites';
this.callFifo.push('addElement');
break;
case 'addotherassignment':
this.callFifo.push('requestLock');
this.elemtype = 'otherassignment';
this.callFifo.push('addOtherassignment');
break;
case 'addassignment':
this.callFifo.push('requestLock');
this.elemtype = 'assignment';
this.callFifo.push('addAssignment');
break;
case 'addimage':
this.elemtype = 'ebookimage';
this.callFifo.push('createImage');
break;
case 'joinimage':
this.callFifo.push('requestLock');
this.elemtype = 'joinimage';
this.callFifo.push('addElement');
break;
default:
return false;
}
this.callNext();
}
Authortool.prototype.finishAuthoring = function(){
/******************************************************
* Finish adding element in chapter/section/subsection
******************************************************/
this.callFifo.push('getUpdates');
this.callFifo.push('saveNewElement');
this.callFifo.push('sendContent');
this.callFifo.push('removeLock');
this.callFifo.push('endAuthoring');
this.callNext();
}
Authortool.prototype.addElement = function(){
/******************************************************
* Tool for adding element in chapter/section/subsection
******************************************************/
// if (elemtype == undefined){
// return false;
// }
var tool = this;
this.addelemdata = {
'pageview': jQuery('#pageOne > [tiddler]').attr('tiddler'), // chapter/section/subsection, where element is added
'beforeafter': '', // Before or after the reference element
'refelement': '' // The reference element for the place of addition
};
this.adders = {
'tableelement': this.createTableElem,
'examplesd': this.createSd,
'examplebox': this.createExample,
'theorybox': this.createTheory,
'textelement': this.createTextelement,
'discussion': this.createDiscussion,
'prerequisites': this.createPrerequisites,
'joinimage': this.joinImageElement
};
tool.addelem = tool.adders[tool.elemtype];
var assignmentlist = jQuery('#pageOne').find('.sdbookassignmentlist');
if (assignmentlist.length == 0){
// var pageElements = jQuery('#pageOne > [tiddler]').addClass('addelems').children('[tiddler]');
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
pageElements.eq(0).prepend('<div class="addelembefore"><a href="javascript:;" title="Add element before">↰+</a></div>').end()
.append('<div class="addelemafter""><a href="javascript:;" title="Add element after">↲+</a></div>')
.find('.addelembefore a, .addelemafter a').click(function(){
tool.addelemdata.beforeafter = 'after';
if (jQuery(this).parent().hasClass('addelembefore')){
tool.addelemdata.beforeafter = 'before'
};
tool.addelemdata.refelement = jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
var page = jQuery(this).parents('.addelems').removeClass('addelems').attr('id');
jQuery('.addelembefore, .addelemafter').remove();
tool.addelem();
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('addelems');",30);
if (pageElements.length == 0){
this.addelem();
jQuery('.addelems').removeClass('addelems');
}
} else {
alert('You can not add this element on assignment page.');
}
}
Authortool.prototype.addInTiddler = function(){
/******************************************************
* Tool for adding <<tiddler>>-macro in chapter/section/subsection
******************************************************/
var tiddler = store.getTiddler(this.addelemdata.pageview);
var content = tiddler.text;
var reftiddler = '<<tiddler '+this.addelemdata.refelement+'>>';
var newtiddler = '<<tiddler '+this.tiddlerName+'>>'
if (this.addelemdata.refelement == ''){
content = content + '\n' + newtiddler;
} else if (this.addelemdata.beforeafter == 'before'){
content = content.replace(reftiddler, newtiddler + '\n' + reftiddler);
} else if (this.addelemdata.beforeafter == 'after'){
content = content.replace(reftiddler, reftiddler + '\n' + newtiddler);
}
var now = new Date();
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now);
autoSaveChanges();
this.sendFifo.push({"title": this.addelemdata.pageview, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
}
Authortool.prototype.removeElement = function(){
/******************************************************
* Tool for remove element in chapter/section/subsection
******************************************************/
this.assignmentlist = (jQuery('#pageOne').find('.sdbookassignmentlist').length != 0);
if (!this.assignmentlist){
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
var elementType = '[tiddler]';
}else{
var pageElements = jQuery('#pageOne .sdbookassignmentlist .assignmentAccordion0 h3');
var elementType = 'h3';
}
if (pageElements.length == 0){
alert('Nothing to remove.'); //Localization
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
return false;
}
var tool = this;
this.removeElemdata = {
'pageview': (!this.assignmentlist)?jQuery('#pageOne > [tiddler]').attr('tiddler'):jQuery('#pageOne .ebookbox [tiddler]').attr('tiddler'), // chapter/section/subsection, where element is added
'removedElems': [] // What Elem to remove
};
pageElements.append('<div class="removethis"><a href="javascript:;" title="Remove this element"><span>X</span></a></div>').end()
.find('.removethis a').click(function(){
if(jQuery(this).parent().hasClass('selectedRemove')){
tool.removeElemdata.removedElems.remove(jQuery(this).parents(elementType).eq(0).attr('tiddler'));
jQuery(this).parent().removeClass('selectedRemove');
}else{
jQuery(this).parent().addClass('selectedRemove')
tool.removeElemdata.removedElems.push(jQuery(this).parents(elementType).eq(0).attr('tiddler'));
}
return false;
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('removeelems');",30);
}
Authortool.prototype.removeInTiddler = function(){
/******************************************************
* Tool for removing <<tiddler>>-macro in chapter/section/subsection
******************************************************/
if(this.removeElemdata.removedElems==[]){
this.callNext();
return false;
}
var tiddler = store.getTiddler(this.removeElemdata.pageview);
var content = tiddler.text;
var reftiddler = '';
var reExp;
for(var i=0;i<this.removeElemdata.removedElems.length;i++){
if (!this.assignmentlist){
reftiddler = '<<tiddler '+this.removeElemdata.removedElems[i]+'>>';
reExp = new RegExp(reftiddler+'[\n]*');
}else{
reftiddler = this.removeElemdata.removedElems[i];
reExp = new RegExp('\ '+reftiddler);
}
content = content.replace(reExp,'');
}
var now = new Date();
tiddler.set(tiddler.title,
content,
config.options.txtUserName,
now);
autoSaveChanges();
this.sendFifo.push({"title": this.removeElemdata.pageview, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
}
Authortool.prototype.editElement = function(){
/******************************************************
* Tool for edit element in chapter/section/subsection
******************************************************/
var editorviews = jQuery('#pageOne .qededitor');
this.assignmentlist = (jQuery('#pageOne').find('.sdbookassignmentlist').length != 0);
if (!this.assignmentlist){
var pageElements = jQuery('#pageOne > [tiddler] > [tiddler]');
var elementType = '[tiddler]';
}else{
var pageElements = jQuery('#pageOne .sdbookassignmentlist .assignmentAccordion0 h3');
var elementType = 'h3';
}
if (pageElements.length == 0){
alert('Nothing to edit.'); //Localization
tool.callFifo = [];
jQuery('#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel').click();
jQuery('#actionButtons .actionmenu.menuopen button.actionmenubutton').click();
return false;
}
var tool = this;
pageElements.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.tiddlerName=jQuery(this).parents('[tiddler]').eq(0).attr('tiddler');
if (tool.assignmentlist){
var dataTiddler = store.getTiddler(tool.tiddlerName);
tool.openDialog('editassignment', 'Edit selected assignment', ['ebooktitle','level','elem_content', 'tag_insert']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.ebooktitle').append('<h2>Additional title:</h2><input class="ebooktitleInput" type="text" value="'+(typeof(dataTiddler.fields.ebooktitle) !='undefined'? dataTiddler.fields.ebooktitle : '')+'"/>');
tool.dialogbox.find('.level').append('<form><div class="assigment_level_changer"><input type="radio" id="level0" name="level" value=0 /><label for="level0">*</label> <input type="radio" id="level1" value=1 name="level" /><label for="level1">**</label> <input type="radio" id="level2" value=2 name="level" /><label for="level2">***</label></div></form>').find('.assigment_level_changer').buttonset();
tool.dialogbox.find('.level .assigment_level_changer #level'+DataTiddler.getData(dataTiddler.title,'level',0)).click().change();
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text.replace(/<data>[^<]*<\/data>/,'')+'</textarea>');
}else{
var dataTiddler = store.getTiddler(tool.tiddlerName+'_data');
tool.openDialog('editcontent', 'Edit selected content', ['elem_content', 'tag_insert']);
//tool.dialogbox.find('.tag_insert').append('Insert tags <input class="tags_input" type="text"/>(separate tags with space)');
tool.dialogbox.find('.elem_content').append('<h2>Text content:</h2><textarea class="elem_content">'+dataTiddler.text+'</textarea>');
}
tool.save = function(){
var content = this.dialogbox.find('.elem_content textarea').val();
if (tool.assignmentlist){
var assignmentData = DataTiddler.getDataObject(dataTiddler.title);
assignmentData.level = this.dialogbox.find('.level .assigment_level_changer input:checked').val();
this.saveTiddler(dataTiddler.title, content+'<data>'+JSON.stringify(assignmentData)+'</data>', [],this.dialogbox.find('input.ebooktitleInput').val());
}else{
this.saveTiddler(dataTiddler.title, content, [],'');
}
this.sendFifo.push({"title": dataTiddler.title, "newTiddler": 0});
refreshElements(jQuery('#pageOneWrapper')[0]);
this.callNext();
return true;
}
jQuery('#pageOne .editthis').remove();
jQuery('#pageOne > [tiddler]').removeClass('editelems');
jQuery('#actionButtons #actionbutton_Edit').click();
});
editorviews.append('<div class="editthis"><a href="javascript:;" title="Edit this element"><span>Edit</span></a></div>')
.find('.editthis a').click(function(){
tool.qedelem = jQuery(this).parents('.qededitor');
jQuery('#pageOne [tiddler].editelems').removeClass('editelems');
jQuery('div.editthis').remove();
tool.qedelem.before('<div class="sdauthorbuttons"><a href="javascript:;" class="sdauthorbutton_send">Send SD</a></div>')
.prev().find('a.sdauthorbutton_send').click(function(){
jQuery(this).parents('.sdauthorbuttons').remove();
jQuery('#actionButtons .actionmenu.menuopen button#actionbutton_Edit').click();
tool.sendSd();
}).button();
var tiddlerName = tool.qedelem.parents('[tiddler]').attr('tiddler');
var tiddler = store.getTiddler(tiddlerName);
tool.oldcontent = tiddler.text;
tool.cancel = function(){
tiddler.set(null, tool.oldcontent);
autoSaveChanges();
}
tool.sendFifo.push({"title": tiddlerName, "newTiddler": 0});
tool.qedelem.find('.qededitorbuttons a.command_qededit').click();
});
// Ugly timeout-hack for Firefox!
setTimeout("jQuery('#pageOne > [tiddler]').addClass('editelems');",30);
}
Authortool.prototype.sendSd = function(){
/******************************************************
* Tool for sending structured derivations
******************************************************/
this.qedelem.find('.qededitorbuttons a.command_qedclose').click();
this.callNext();
}
Authortool.prototype.checkUpdates = function(){
this.updtiddlers = [];
var tool = this;
var callafter = this.callFifo.shift();
if (typeof(callafter) != 'string' && typeof(tool[callafter]) != 'function'){
callafter = 'emptyf';
}
var callback = function(data){
try {
var respdata = JSON.parse(data);
} catch(err) {
var respdata = {"tiddlers":"","tiddlerlist":[]};
}
if (respdata.tiddlers != ''){
tool.updtiddlers = respdata.tiddlerlist;
}
if (tool.updtiddlers.length > 0){
tool[callafter]();
}
}
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {"lastCheck": "0"});
var updateurl = configs.updateURL;
var lastCheck = upddata.lastCheck;
var response = jQuery.postCORS(updateurl, {"checkUpdate":lastCheck, "bookName": this.bookid}, callback);
testilogit.updateresp = response;
}
Authortool.prototype.getUpdates = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var upddata = DataTiddler.getData(Emathbook.config.userdatatiddler, 'updates', {"updateURL": "", "lastCheck":"0"});
var updateurl = configs.updateURL;
var lastCheck = upddata.lastCheck;
var now = new Date();
var nowtime = now.convertToYYYYMMDDHHMMSSMMM();
var tool = this;
var callafter = this.callFifo.shift();
if (typeof(callafter) != 'string' && typeof(tool[callafter]) != 'function'){
callafter = 'emptyf';
}
callback = function(data){
store.importTiddlyWiki(data);
var updelem = jQuery(data);
var numberOfUpdates = updelem.find('div[title]').length;
if (numberOfUpdates > 0){
upddata.lastCheck = nowtime;
DataTiddler.setData(Emathbook.config.userdatatiddler, 'updates', upddata);
autoSaveChanges();
refreshElements(jQuery('#pageOneWrapper')[0]);
}
tool[callafter]();
}
var response = jQuery.postCORS(updateurl, {"getUpdate":lastCheck, "bookName": this.bookid}, callback);
testilogit.updata = response;
}
Authortool.prototype.sendContent = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var senditem = this.sendFifo.shift();
if (typeof(senditem) == 'undefined'){
this.callNext();
return true;
}
if (senditem.system) {
var system = 1;
} else {
var system = 0;
}
var tiddlerName = senditem.title;
var tdata = store.saver.externalizeTiddler(store, store.getTiddler(tiddlerName));
var userName = config.options.txtUserName;
var now = new Date();
var nowtime = now.convertToYYYYMMDDHHMMSSMMM()
var data = {
'sendUpdate': nowtime,
'author': userName,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookName': EbookPages[0].ebook.bookid,
'systemUpdate': system
};
if (typeof(senditem.newTiddler) == 'undefined'){
data.newTiddler = '1';
}
var tool = this;
var response = jQuery.postCORS(updateurl, data, function(repdata){
testilogit.resp = repdata;
if (repdata != 'Ok'){
var tiddler = store.getTiddler(tiddlerName);
tiddler.tags.push('notsent');
tiddler.set();
}
tool.sendContent();
});
}
Authortool.prototype.requestLock = function(){
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var tool = this;
var callafter = this.callFifo.shift();
if (typeof(callafter) != 'string' && typeof(tool[callafter]) != 'function'){
callafter = 'emptyf';
}
callback = function(data){
var datanum = parseInt(data);
if (datanum == -1){
alert('Sivu lukossa. Yritä myöhemmin.'); // Localization
} else {
tool.containerLockId = datanum;
tool[callafter]();
}
}
var response = jQuery.postCORS(updateurl, {"setContainerlock":this.container, "bookName": this.bookid, "author": config.options.txtUserName}, callback);
testilogit.lockresp = response;
}
Authortool.prototype.removeLock = function(){
if (typeof(this.containerLockId) != 'undefined'){
var lockid = this.containerLockId;
} else {
var lockid = 'all';
}
var tool = this;
var configs = DataTiddler.getData(Emathbook.config.datatiddler, 'config', {"updateURL": ""});
var updateurl = configs.updateURL;
var response = jQuery.postCORS(updateurl, {"removeContainerlock":lockid, "bookName": this.bookid, "author": config.options.txtUserName, "container": this.container}, function(){tool.callNext();});
testilogit.lockresp = response;
}
Authortool.prototype.emptyf = function(){};
/************************************************************************
* EmathbookAssignnment -class
************************************************************************/
EmathbookAssignnment = function(placeholder, assignmentType, assignmentText){
if (typeof(assignmentType)=="undefined"){
this.assignmentType = -1;
}else{
this.assignmentType = assignmentType;
}
this.data = {"assignmentType": this.assignmentType};
if (typeof(placeholder)=="undefined"){
this.placeHoldertype="lose";
this.placeHolder = "";
}else{
if (store.tiddlerExists(placeholder)){
this.placeHoldertype="tiddler";
} else {
this.placeHoldertype="holder";
}
this.placeHolder = placeholder;
}
if (typeof(assignmentText) =="undefined"){
this.assignmentText = "";
}else{
this.assignmentText = assignmentText;
}
}
_ = EmathbookAssignnment.prototype;
_.setData = function(type,value){
if (typeof(this.data[type])=="undefined" || typeof(this.data[type])=="string"){
this.data[type] = value;
}else if(typeof(this.data[type].pushUnique)=="function"){
this.data[type].push(value);
}else if (this.placeHoldertype == "tiddler"){
this.data = DataTiddler.getDataObject(this.placeHolder);
}
}
_.setText = function(text){
if (typeof(text)=="undefined"){
if (this.placeHoldertype == "tiddler"){
var tiddlerText = store.getTiddler(this.placeHolder).text;
this.assignmentText = tiddlerText.replace(/<data>[^<]*<\/data>/,'');
}
}else{
this.assignmentText = text;
}
}
_.saveToTiddler = function(tiddler){
if (!store.tiddlerExists(tiddler)){
var saveTiddler = store.createTiddler(tiddler);
}else{
var saveTiddler = store.getTiddler(tiddler);
}
saveTiddler.tags.pushUnique('assignment');
saveTiddler.set(tiddler, this.assignmentText+'<data>'+JSON.stringify(this.data)+'</data>');
autoSaveChanges();
}
_.dataString = function (){
return JSON.stringify(this.data);
}
/*********************************************************************
* Actionmenu-class
*********************************************************************/
function Actionmenu(menuname, clickopen, clickclose){
this.menuname = menuname;
this.menuitems = [];
this.clickopen = clickopen;
this.clickclose = clickclose;
var menuid = this.menuname.replace(/[^a-zA-Z0-9]/g,'');
this.menuelement = jQuery('<div id="actionmenu_'+menuid+'" class="actionmenu"><div class="actionmenucontainer"><ul class="actionmenuitemlist"></ul></div><button id="actionbutton_'+menuid+'" class="actionmenubutton"><span>'+menuname+'</span></button></div>');
this.menuelement.find('#actionbutton_'+menuid).button().click({'menu': this, 'clickopen': clickopen, 'clickclose': clickclose},function(e){
var menuchoice = jQuery(this).parents('.actionmenu');
menuchoice.toggleClass('menuopen');
if (menuchoice.hasClass('menuopen') && typeof(e.data.menu.clickopen) == 'function'){
e.data.menu.clickopen();
} else if (typeof(e.data.menu.clickclose) == 'function'){
e.data.menu.clickclose();
}
});
}
Actionmenu.prototype.pushItem = function(item){
var newitem = new ActionmenuItem(item, this);
this.menuitems.push(newitem);
this.menuelement.find('ul.actionmenuitemlist').append(newitem.menuItemElement);
}
Actionmenu.prototype.addMenu = function(addplace){
if(typeof(addplace)=="undefined"){jQuery('#actionButtons .buttonbar .editbuttonset').append(this.menuelement); return true;}
if(typeof(addplace)=="string"){addplace = jQuery(addplace);}
addplace.append(this.menuelement);
}
// Actionmenu.prototype.addMenu = function(){
// jQuery('#actionButtons .buttonbar .editbuttonset').append(this.menuelement);
// }
/*********************************************************************
* ActionmenuItem-class
*********************************************************************/
function ActionmenuItem(menuitem, parent){
this.parent = parent;
if (menuitem == undefined){
menuitem = {};
}
if (menuitem.name != undefined){
this.name = menuitem.name;
} else {
this.name = 'emptyname';
}
if (menuitem.contexts != undefined){
this.contexts = menuitem.contexts;
} else {
this.contexts = ['chapter','section','subsection','frontPage','assignment'];
}
if (menuitem.title != undefined){
this.title = menuitem.title;
} else {
this.title = this.name;
}
if (typeof(menuitem.click) == 'function'){
this.click = menuitem.click;
} else {
this.click = function(){
alert('No action');
}
}
if (menuitem.level != undefined && typeof(menuitem.level) == 'number'){
this.menulevel = menuitem.level
} else {
this.menulevel = 0;
}
var contexts = [];
for (var i = 0; i<this.contexts.length; i++){
contexts.push('context_'+this.contexts[i]);
}
var classes = contexts.concat(['level'+menuitem.level]);
var classesstr = classes.join(' ');
this.menuItemElement = jQuery('<li class="'+classesstr+'"><button class="actionmenuitem_'+this.name+'"><span>'+this.name+'</span></button></li>');
var edata = {'menuitem': this};
this.menuItemElement.find('button').button().click(edata, function(e){
if (e.data.menuitem.menulevel == 1){
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level1').addClass('level2');
} else if (e.data.menuitem.menulevel == 2){
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level2');
} else {
e.data.menuitem.parent.menuelement.find('ul.actionmenuitemlist').removeClass('level1 level2');
}
e.data.menuitem.click();
});
}
//}}}
//{{{
jQuery('#actionButtons .editbuttonset,#actionButtons .attachbuttonset').hide();
jQuery('#actionButtons').hide();
var initType="reading";
if(typeof(Authortool) ==='function'){
initType="author";
}else if(Emathbook.options.pages[0].courseid !==''){
initType="course";
}
Emathbook.initBook(initType);
//}}}
!usage
{{{[img[background-paper.png]]}}}
[img[background-paper.png]]
!notes
Paper background for history elements.
!type
image/png
!file
!url
!name
background-paper.png
!author
Pesasa
!source
E-math
!license
pd
!data
data:image/png;base64,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
!usage
{{{[img[book-icon.png]]}}}
[img[book-icon.png]]
!notes
icon of book
!type
image/png
!file
./data/images/book-icon.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookicon_default.png]]}}}
[img[bookicon_default.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf-left.png]]}}}
[img[bookshelf-left.png]]
!notes
Image for left bookshelf corner.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf-right.png]]}}}
[img[bookshelf-right.png]]
!notes
Image for right bookshelf corner.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_left.png]]}}}
[img[bookshelf_line_left.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_left_black.png]]}}}
[img[bookshelf_line_left_black.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_left_darkgreen.png]]}}}
[img[bookshelf_line_left_darkgreen.png]]
!notes
Bookshelf line
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_left_notes.png]]}}}
[img[bookshelf_line_left_notes.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_left_pink.png]]}}}
[img[bookshelf_line_left_pink.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_right.png]]}}}
[img[bookshelf_line_right.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAG4AAABkCAYAAABnwAWdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpQAACKUBTTjBigAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABgdSURBVHic7V1rdFxXdd77nHPvnYfH0kgaWxYicRLHcTIJBCik0BLURcsjFNpCCY+WR8urq9CGQkqhQCynPAttUlJYpYtnEzDEIQ4N0IamqZKQd9JQw6Qgp+CAM5Y9kUevuc9zzu6PuWdyNZ7Ry9JItvWtNcuKrdx7Zr7Z+37fPvucg0QE6zjxwFZ7AOtYGsRqD+BUBiJiu3+jeVIhrqfKzqEVUc2ffysuW5G4TlwHkCSMiGDXrl2N/y6VSo2fi8Vig4ydO3dSksRm8taJW0G0I6xUKmGlUsGhoaFj/p+RkREoFApkSEwSmCRvnbgVQpK04eHhBmHFYhHL5TJWq1Xs7+/HSzL3Odutg7mrJ1/1xNjYGOXzeRoYGKAkgYa8JHHrqnIFYEgjIhgeHsY4HbJ8Ps/Gx8d5GIZ8cHCQvy59S89vpR68dqR6mhcEAR8cHORhGHIAYNu3b8dKpYKlUglNpCa/DOvELTPMhzs8PIy7du3CkZGRWYQFQcAzmYx4g7h+60WZ/bdJ4Afvi56mHMcRk5OTQinFJycnueM4DfLM9ZLXXyduGZEkzURZoVBghjDGmAUA1mVdNz7jwmz5PxnQjv3R4NejKLK11pbjOKK7u5sHQcCFEMyQlxQwBus+bpnQTFqxWESoBwbPZDJcSskRkX+wsHfoqdYTX0GgXET8gX848sLHHEfYURRpxphyXRc552p6epo451Sr1cy1ZomRdeKWAc2kxamRBUHAc7kcJyIRRZH4+FP2vnqzmLgaACwAgEOyZ49t2yki0kopxRiTlmVBFEVgWZYWQlAulyOAhm1okLdO3HGiFWlhGHLP83h3dzf3fd9KpVLWp59y/Z/3iNr7AQABADTg9BePXjwilUwjomKMSQDAMAyJiMiyLOV5ng7DEIMgMKQ1yFt/xi0RGCOpHA1pSimeTqdFEAR2l63Sn+j78id6RO0DEJMGADAuc7eUozxnjKWJKKW1tonIEkIIzjnjnLNcLjfr2TY8PNz4eT3iloCk3DfKMRYhLJPJCNd1BWPMPp09nrus75bPpln44uZr3OGe930AyBCRRMTIsiySUioAkIwxFoYhElHbWua6AV8kkqkx/itWKpUYAPBCocCJyIqiyL54w+jm13Td/SUb5bOarzGjU/vfc+gNlwOARsSQiAKttWdZlqu19hhjPufc9zwv1FpHtm2rarWq9+zZowHqFZT1VLkItJL7pVKJDQ4O8lwuJ4IgsBHReeXG+896Xddde1uRBgBQCgZHACDDGEshogMAlhCCIyJTSrWNsiTWiVsg2sn9fD4vJicnhZTS5pw7b9jw/We9KPfjmwSqM1tdRxHzvzV50T4AyBjSAIAjItNao+M4jd9NpVKNdGhql6bstf6MWwDmkvuO4wjLsizP85zLer7zm+emDn0OgbLtrnUgKjw8oTIcER0iIq11BABMa42ICEEQABERIlIYhtTd3U29vb3HPM/WI24etCLNcRwWBAEHACsIAlspldq55V9fd26q/MW5SAMAuK12/sMAkCIim4g4YwwBAJRSpJQi27Z1KpXSuVxOp9Np6u3tpVKpdAxx6xE3B9qRNjExIdLptIiiyOacOx/ZtPvdBTH93vmuV1XZww/5244ikg0AEhEZAABjjBhjWmutiEgTkXZdl6rVKkHs24aHh2eRtx5xLTCXR5uYmBCcc4sx5vRmWObTW77+yYWQBgDwkHdmiYgcRBQQf/ZEpAFASSlVbMSV1lpLKXU2m6WBgQFqfr4BrBN3DFp5NADgYRjyTCYjent7rVQqZZ8pyt27eq/9Qhd3X7+Q60pi8paZC38OAEJrzWISFCIqpZTinEtDnFJK9/T06FqtplulSYB1HzcLzR7NGGto8mjPz/5ky2u67/2yg/LChV675A8++pmjl4wgYo2IphBxQmt9FACOElEVACYBYBoAXMaYn81mw1qtJo1/a25dWI+4GO2mZJo92qX5B7e/vvueGxdDGgDA7d75P4cnP29NRBIAIvPinEvbtiVjTEkpdbVanZUmm7FOHLT3aIODgzzp0d604ZZnvzC7b69AdcZirj+uclP7/NOrAPVnGiJKAIgQMWSMhRCT5/u+4pyrKIr01q1bdalUop07d7Yk7pRXlfN5tHQ6bXme57yn77sv2m6XP4tAmcXe4z532y/jHzUASK11REQh5zxkjIVEFCJiZNu2FEIo3/d1uVymYrF4TK+JwSlLXHMzTxuPZjHGnF1bvv0Hg9b4xwCAL/Y+kpi+baZYjk21jEkKGGMBAARKqRAAIimldBxHKaV0f3+/bmW6kzgliWtWjs3zaEmP9tFNu9/TJ6b/Yqn3eiQYrMxANkCsRxoAhIgYxIXlUAhhCsmyVqsp27Z1pVKhsbEx2rNnD7XraD7lnnFzkdbX18eNR+viXvbvBr72qeMhDQDgTvfcstZaQfxMA4CAiAJE9IUQAec8BIDI8zzFGFNhGOpisajbiRKDU4q4ZtIg7gkxHq1Wq9lCCOds62D+owM3fmkj8157PPcbVzl/n3/6UZMiAcAHAB8RfSIKiCgIwzCybVumUim5EFFicMoQlxQhl156KYPEPFomkxHGo70g+8jAu3r+/foMC3/jeO95n3v2YQCIiCg0UWZeRBTEwiSSUkohhOrr69Plcpni8c658OOUIG4uuZ/0aK/JP3DOa7vv22ujfNrx3lMBo9u94iGoS/0AEX2ttY+IHgD4QoggiqIonU5HnHOllNJSSj2Xd5v1nk72yslc1f1arSY451YqlbLflr/12c9MH/gyA92zHPf9UXBa9bNHX/owEVWJqIKIFQA4TEQVxtg4EVWVUlOO48y4ruvbth1Wq1UJAOr666/X0NSO14yTWlXORZrjOAIAbCmlfXnfd16yzT70jwiUXq57/6C2YyyW/j4A+ETkMcZ8ImqkSaXUMaIEAIx3m/P6J2WqNNV9gNZTMhDPozHGnCu33PTGs+3yPy8naUfVhnBfsPUJAEgKEk9r7UOsKpVSoWVZx4iShd7jpIu4+Twa59xyHMfyPM/52Obd7+vl03+23GO43zu7ognCWIT4ROQBgM8Y87TWvok2KaVkjOmkKBkeHm7r3ZI4qSKu1ZSMIS2TyTSeZ10wseHvB7521UqQpgHpdve8sdhg+4jomRfUyQuVUqFt29JxHCmEUIsRJY33erKIk3Ztc9lsliXl/vnpcv7tPbf+UxrDF6zEOErB4ORnxi/5IQCMA8ATAHAYAI7E4uQJI0o457UwDL1mUTKfDTA4KVJlK7lvPBpjTARBYCml7Bd3/2TglV0PftVGef5KjeUud8dhAAggfq4RkQ8AvlLKZ4w1REkURTKKIg0A2ixmXChpACdBqpzPoyGixTl33rjpoXN+v+uBm1aStAmVjf7b3VqBmLj42eYRkWdMd9y1LBljijGmcrkcjY6OLjrtndARN9+UjJTSSqVS9jvy/3HRhenHvsRA51dyPPd7254AxgOoCxKfMWaI8znnQVz2iqSUknOu+vr6dK1W04VCgZqbgebDCRtx83m0IAhsIYTzl4WbX/aM9IHdK02aBoTba3VRAk+myVnRxjkPETFijKlWomShaRLgBCRucR5t7x9vsw59HoFSKz2u0WBg6gmVm44Nd4MwQ5pSKgyCIJJSykwmI6WUemxsrGXP5EJwQqXKRXq09/fy6Xd2amx3uecciSv+yRTZiDYjShzHkZVKRVuW1RAlC/VuSZwwETdf29xsj3bd1Z0kbUqnowfcM46YCIsrJF4cfYGZd7MsS7que1yixOCE8HHtPBo0tc09PXOw5y352z6fxvD5nRzfbbULxq6fet4jRDSOiBUiOgIAR4joCOd8XCk1IYSYiqKo1qr1DmBxzzeAEyDiWrXNGdLMlIznec5Lu/938O35W/d0mjQChJGEKElaAIjrknGabNt6t1jSANY4cQv1aG/e9MC5r8jec5ONstjpMT4a9k8fll1Tpi6ZLG9B3Xg32u9M691cHcoLxZoVJwvxaEII5x35W557YfoXX2BA3asxzrvdHUcQcValJCbQ11oHjLEQESNEVFNTUyoMw+MSJQZrMuIW6tE+0P+9lz8j/YuvrRZpMzol7/fOPAL1lNiINsaYZ5qBIDbcURTJrq4u3d/fr49HlBisKeKMR2teJZP0aDMzMw5jzPmbLXvfus0e+xwCOfNeeIXwoHfWuCRuVKRvDHf8c6CUCjnnoamUOI6jxsbGaCmVkmasGeLm8mhmaZPjOPVex8J1Hx6wqrtgFcdPAHB77bwxiPtJjCgxc25JUWLbtjSiJNl6t9Q0CbBGiFuoR+uF8Q1XDVx3TQ+feccqDxl+Hm6eeTzqnoL42WYEiVLKRF8jTS6nKDFYdR+3UI/2zMwvev4oP/KFFIbPW73RPonrJl/wsztr5/wM6nNsFUQ8TERHELGitR5njE0wxqYBwLUsyx8bG4vy+XzbZVOLxapGXDuPlmyb8zzPeXn+x6e9JX/bjWuFNFc76l532+FEn+QsUWJW4Egppeu6jfUAo6Oji5rlngurZgfm8miTk5MNj/aHPXcXn5/56Vc56oHVGmszHvLPHI+I+0SNPknTS9LoUEZE01OipJS6UqksiygxWJWIa+PReLlcFlJKK51O20SUemfv93/94uxPblhLpAEAjMyc2xAlzdFmnm0AEJmFis3rAY43TQKsAnEL8WhKqdQH+7/7uxc4j13LgLo6Pca58FhUqD2uCpMQV0aSXVxGSTLGwpUSJQYdI26hHk1rnbqi9xtvP9M+fM1qerR2uDuevoGEbzMWAOL1bti0SDGfzy+q9W4h6AhxC/VoFqr0327ZfcUWa+KKTo1tMfDIVne72480i5KkBTDRlhQli229WwhWXJy08mjNWwSmUim7V43l3jt481UbmP/ylR7TUvGwd0Y10NxDpEaJy0yWaq0DrXXIOT9GlJhFiss5lhX9ViefZ2Y9mtl+wvQ6CiGcC8T+wl8VbrpuLZMGADBSO/cQtKlLmmiDFRYlBitG3EI8GiI6v931o61v6x35VgqjX12psSwHfhn1uo9FmyYhrpRAbAEgFilCiKBZlCx2PcBisCKpcqEe7bXZ2y54Xmb0Kxz1lpUYx3LiHu+cI5CoS8aRZvxboJQKhRANUbKU9QCLwbJHXCvSWnm0P83/28W/lv3pnhOBtIAsfVftnMMweymwp7WeZQOSomQp6wEWg2Ulrp2xTno0RHQ+1P+d33ta+uC/MKCNy3n/lcIP/a1VTwtDkhEkjWebmeVO7gxkWu/mW8u9VCxbqpyr1zGdTouZmRnbcRz7g93X/km/mPxrWINyvx1ur507xhgLEkuBZ5W4krXJNosUl528ZfnwWpHW7NFSAlIfL1x7Zb+Y/NBy3bcTKMu8939hfzUhRBqmm4iC5Cx3J0SJwXFHXDvSkh5tMx7Z8O4tN30my4KXHf+QO4t73O0ViEUJ1HslG2kSEs1AnRIlBsf1zW9VwjKkGY/2LGd/4fL8jbtPRNJCEvoH7o4xiEUJxClSKWVejU3UOiVKDJZMnCEtOWOdzWYFY8wyIuQVGx86403dI3sdjJ6zjGPuGPb5p094lHKhHnGNaGtOk50UJQZLIs6QZjZ6Mfs6Jj3a67O3Pv2Sjf9zk4Xq7GUec8dwh9uYvjFtd40SlxCioSaTOyfk8/k5d71bLiyaOEREszuP8Wj5fH6WR3tX/ntDz83uv4GD3rwSg+4ExmS3/9Ng4GiLtdyNyVKIoy25c0K1WtWdGN+CxclcDaqQ2CLww1tuftXpVuXTGB+1daLiXvfsCiTqkmbOzRSUOeeNnRMsy+qYKDFYUMS1EyFmHi0+cTC1q/CNd261Klef6KRFxOmO2o7DcQtCI02aTi4iCqIoarSVd1KUGMxLXLMIad5+gjHmWKjSn9qy+yOb+MSso7ZOVPw4OG2iRumakfwmTcYps1FQNntMdlKUGMyZKpOkwZPnfbKE3LcH+ZHcuwe/e02WBS/pxIA7gTtrO8YgXoAPseE26wHiv4+UUjKKolmiZLE7JxwP2kacESGGtFZbBD4n/eimy/tu3n0ykVaRG4NS8NRxiOuSzfNuSqlQKRWm0+mIMdaolCzHeoDFoCVxJtLM77RqUP2djQ+e8eaeO/c6GP1Kx0bbAdzrtRQlsyZLiaixY7kRJab1rhPRBtCCOKMeTW9IuVzGbDbLkqS9pee/Lnzpxn3ftlCd1YlBdgqSGN1Rn+VuFJOTosR4t+Pdzmk50DLimiv8Sinuuq4gIut9m783dFHmZzdw0Js6OdBO4JHgqRNTOjNjIs2QZkSJUiokoggAotUSJQazxImJNgCAeNYay+Uyjw8VF1f0ffPV/aJ61Yku99vhB+6OskmNUD8qxRx96QFAyz0mOy1KDI6JOBNt5XIZDxw4wIQQzHVd8cnN1122RVSvOVlJO6o2+Pv80w5h/eybGiLWAMCNX40J03Q6HSUrJZ0WJQYt7UAi2thGmrCueMoNn0yz8K0dHltH8YB31uMEOAMAM4yxGQCoKaVczrnpm2xMlmqt9WqJEoNGxBklaaJtfHwcL+l9NH3lpm9+9WQnTQPSyMx5+6F+mtQ0Ec0Q0UwcfR4i+pZlBRBP36ymKDFoyH7j25IlrXPSlfRZ1qG8C2nbx0zaVSITkpWVaOUihRsV8pwmtlEDbtAEGwhZBggymiAFiA4iWkQgCEBg/XRCRvFJyMnnaRIr9cU1t6M6NCJKBJBEOiRkbk2nJqBO2gQiHgWAo4h4VCk1AYkjwqSUwVL3mFxOtEyV1WoVBwcHcf8kkwfZ1kmlVCqKIimEMINkWmvOGGNExBIDV1BfqeIDgQXxibtExOOIZowxoDkOJm+Fxf5+KyCi+WDrO4wTSKofnh6QJh8RagAwjYiTiDiltZ5hjNU45x5jLIiiKHIcR2qtV1WUGMxZ8gqCANPpJ/eYVkoR51wDgOKcR/EMsB8TA0SkiChkjFlEJCCOtDjKsMnYA8DykLIQEJEhj6BOnsL6NhZhPE3jIuKM1nqacz6JiNNSSjeunAQAEMVfXjUwMKBLpZIeGFi91V9tiTt48CDkcjnyfZ845xoRFSIqrbUEgDDe7ZQrpZBzrokoovpuqIY0TkQcnlyoY9YQzCKqTcZcEdS/N0SIqHX9/GYJ9UOKwrhP0uWcm+fbNAC4iOiHYRgiYiSEUK7rdnT6ph1aEpfP5ykMQ0qlUkREFEWRZowpIori6gFDRFRKEWNMQr1E5AGAxRgTMWHMEEZESEQdi645QIY8ANCIKLXWMt5Exo/7SYwFcInIZYz5QojQVEoqlYqu1Wq6WCzSnj17Vu2NzBInph3BzGybRlattRVFkc0Yc7B+WrwjpXQQ0dFa24hoIaLA+mm7HOoiBIkIzTnXAABa61UljjFGiEhaa6L6acA6/uJFcQt5gIi+lLIxYaqUCizLCj3Pk93d3bK3t1eVSiVaLVFicEzEFYtFGhkZwUKhQNlsVgshtOu6yrbtKAxDTKfTJKU0bzjknFtKKcE551JKhoiMc26iDOM3hwAAjK1uOyUikpQSGGME9XNKtdZacc6leT9BEES2bQdhGIZCiJAxFnmeJznnKggCXSqVOtJTMu97Sd47aQnMQo3JyUkeBAF3XVfYti2EEKL+noSIokjYts211hwRWf2xUf/TXLNVlFnW6hRfoigyh6VTnOYJERURaaWUtCxLSiklAERhGMpUKiUNabZtq9HRURoaGtI7d+5ce8SZidNkkVkIwYIg4FJKrpTiWmvOOW9YAlY/vBoty0IpJQLUCXOcNbcSGIIgAMYYCSEoiiLinJPWWptdyTnnqlarKbNvsuM4KggCvZZIA2iRKhERhoeHoVgsUqlU0vl8Hnp7e+nAgQNk27Z2HEdxztn09DTjnDPHcTCKIowjC4WoX1JKifW2jLUF27YJAMCyLAqCADjnRESac05KKR2GobZtW4VhqAcGBnS5XKZqtaqHhoYa57qtBRzjq4xsNzv9mLRZLpfRcRw2PT2N+Xwea7Uabty4EV3XRd/3EaDu+3p6luUUrxVHrVYjAIBUKkWZTIampqYom81StVqlrVu36nK5TAMDA2SeaSbSAJZ3ZelS0XJLqITnaqRNgHrxuVwuY7VaxWKxCOPj4wgAMD09vTa+hktALpcjAICxsTEyuyOMjo5SoVBo1CHXGmkAc+zllawlJvbZAkMiAEClUsGhoaGVHF9HkFxZkywaJ3cBWiuEGcy7CVtzMdj8ftxEdNLAzGA3P8PWGmEG/w9rF3JDuCMQjgAAAABJRU5ErkJggg==
!usage
{{{[img[bookshelf_line_right_black.png]]}}}
[img[bookshelf_line_right_black.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_right_darkgreen.png]]}}}
[img[bookshelf_line_right_darkgreen.png]]
!notes
Bookshelf line
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_right_notes.png]]}}}
[img[bookshelf_line_right_notes.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bookshelf_line_right_pink.png]]}}}
[img[bookshelf_line_right_pink.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bottommenu-left.png]]}}}
[img[bottommenu-left.png]]
!notes
Teacher tools menu icon.
Openclipart.org, tango
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[bottommenu-right.png]]}}}
[img[bottommenu-right.png]]
!notes
Ebook settings menu icon.
Openclipart.org, tango
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[button-bg.png]]}}}
[img[button-bg.png]]
!notes
background gradient for buttons / blue
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAABGCAYAAAAEo14nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKsAAACrABvY1x8QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABNSURBVDiNY7z19Ot/BjTAhC4wKjgqOCpIHUEWjOzGwMDA8v8/pjDLv39YVWIR/IdNOx1VYnUnNh9hVYlFFJeZFLpzQP2OPTaJ9zumKAACq0ckYXb5kQAAAABJRU5ErkJggg==
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAO+SURBVDiNfZVNaFxVFIC/+95k3ryZTJOOmWQ6iiYxTkwbF5WQFkzxBxubxIYaXAkJLUhBgnUhJLjqUgi4EES6cGEzNdB2IdRomooVbYwiFlFi00IjLjR1ZpLRyUwyeb/XRe6EaVI8cHg/nPOdc885914hpWSnCCH0qK4PJAOBQVOI/VFNawQo+n62DLcyjvPZv543LaX0dvnuBEaF6Gw2jKlTsVh7t2kGG3QdAUjAB1Y8jx/LZfvjfP7OspSv5S1r4YFAIYR4IhiceNo0h8fj8aZaIdABTRlKwFPqAkUpeS+Xy/y8uZlesqwxqUDbwDbDmHi7oeGtFyKRYA2gAwFA7AC6Sm2l10sl+8Nc7v3fHWeMSgJRITq7QqGR5xWsBjCAoHpW3mtUEL1Kn62tDR6MRIZjhtEJoAkh9McMY2qssbEpoBxqgA/q6/lhzx5CCliBfeN5TLW0oKnsBTAajyeSuv6JEELXotB/KhZrj6ia6cC5RILXL17kwNQU38ViBNRSvvI82tNp3rhwgW97e7cbYQjBq3V1T4ahX9tnGINdphkUVRGHjh8nFovRmkrRNjnJ1+Ew14pFWtNpug4fpn7vXnpPnMB3XXxV36fC4eA+wxgMhIQ4ENN1APzNTbxSiaazZ7kXCiFGRmhNpeDSJf7J5znY3Y3v+2Tm5sgPDFC2bWxNwzYMQoaB4fvtgVop43Y2i1xfJ+i6WyME1J85w19S8vDJk1tQwPM8svPzrB47hmPbeIDj+9jlMla5TAQe0jzL8pxCAdd17xsJC/h+fJyVTGa7VrlMhi9Pn8a2LBzAqRojX9loa5Ct/HSq5uuaadI+M8Ojra24jkOpWCSRTNJz5Qo/NTdvAytQgDXIaWVYXKmCWcB102T/zAyHjhxB+j5/z82xlE5TLBR4PJXixdlZfmluxlZ+EigAG3Bby8L0TbDsKmDLxASHenrwfZ97c3Ms9/VRGh3lzvnzrBUKtKVS9F++jF211EWwVuFz3YGlZRh6DhKaMjBv3MA5epSNu3f5o68Py7ZxgPWrVykmEgSamrg9NMTm6iqoRM7Br1kYE1JKokJ0PgOzb0JSU0OsBQIgJb7n4atArtrP0jDwLWu7WR/B8jy8VJRyQQMoSrnwG6TnwbaATWDDddnwPMrqu6wy8eA+2E2wb0G6KOUC7Di+HoF3O2B4BJIG/y8WMAnLi5D+E97ZdXxVJCpEZxzSr0BHBxh1O0AF1YBPYTEHw5XMKrILqLLVw9Afg5dN6IjC1hUA2TIs5mF6A7540BXwHx1/r84xJtgPAAAAAElFTkSuQmCC
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASKSURBVDiNdZV7bBRVFIe/OzO7Q3e7LV1aHrUUAg1QCqHQBiFVQitaaaVGI/FBCpJIQHwgMaAmRFKIShofEK0viBIaHiIJGgFTjQaDIErLK7WLECrPUnZl2+1st53Zmbn+QalK8ST3z9+Xc3PP/Y6QUnJ7CSFUPRCo9I/IrfL4/BP1QNpQgF4jFrZ7Ei3xtqvfWEbnPimlMyB7O1APBCelj8rdUfz0i+NHT5/pTQtmIoTAlRJbQiwS4c/GI9bJrR/8YbVfesqIRpvvCBRCiIyxE2rvmjajes7qmmFpfj+6qqAJgQAcKbGkxLRdzv/4Nd7JJfxSt+F65MSx+tj5ltWyD9QPHJw3sfbeFWtWTC57wJvqUfGpCoNUgSYE9AG7TZOmdUspCc7l1wsHiN9zH1eVVOv0Rxs2JVrPrAZQbl0zZ9rdCwtK7/cGPCppHoXBXpUMr0ZQ18jwaijdXfz2egVzZi1l9qxqNi7cy6MdWWSGTngzp86o1oPBSQCKEEJNH5W7o2xVzTCfpuLXFFI1lTSPSoZXJehVSVw5x8/rK6lbW8biygYSabtoJEJF0eNM6UmncF71cD179HYhhKqovkBF4aIXxvtTfOiKQFcEPlXBrymkeVQuHv2Wpk8Xs7n2YYakxuCvLRRnLmZc5iv8TgfPVb5Kyp63yXpsyQR8gQotNTu3KqdohldRQFUEqvjnHNxei3qtgY3rqqD3HHR8CdJCStDMzzGZQVN4Kr2qSVpBkVcfkVOlaT5fQUowEwDLlXQ7EiVp88N7yyjNizF/eRl0N0LsAODiSrhyHYwEtJ9dxrZTD3Lx2Y+J2+DqvvGalhrIilouva4k3QO2hO0LZlL78nRmlxRC1/cQP3zzpV241A6JXjh0UvBFeznXn3mfTtPhhmlj+9OHaL2263QmHUDFo7jcOH0an+Ly2e4QZsdhyqe1AmA7cOEamBbsP6zQwAI6n6whYdkkHBe7b/wU24iFexyXhOMSTzq07NrEoidKWLOyjMazQ6nbMwgrCa1Xb8J2fqfSkPoSsXk1GLZD3HaJ230/sCsaUeyeeCgWCWMkHWJJB+PcKUqKsrDNDubNySV0eQg/HYekDZ985eFQ3ht0lj5PLOnQZTl0JR2kBGJRSBhnNDvcvi984ugipbRST0qJEYkS6wzjVRPYZifz52bz7pYoGRmSM6V1JCbMJm45/Q0k3T4XhJpMboT3C0D1jClozHlnZ6Fz8gjX3lzO8KwUCvL8tEV6sG0HowdSV35IcmIJCdul23YxbIdbLCwT1i46zvnm6UJKiQgEJ+kl5Q2BKcXZ3kO7scfNxJtfjD6+EKkPwpYSy5X0Oi49tovp3qa8LevbOLK/XBpGswYgjWizGDm23pk2a6W+aqtXEwJLQBxwTBvbvQl07uBOmg5atByrl4bRPEBf5Ix5i/ziahauzkYfNDD87zJ7YVttG6HGeq60vjZAX/2CDAQmkTWynkeW5JNfrJMe/C8oFoVQo8nezSEil6tvddaf/78VgC9QQXDoQ6T48wmkDwXAiIXp6Q4RDe8jYRy40wr4GyUNLD/HVcNdAAAAAElFTkSuQmCC
!usage
{{{[img[button-exercise.png]]}}}
[img[button-exercise.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[button-left.png]]}}}
[img[button-left.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAReSURBVDiNhZV9aJVVHMe/55znPs/uy7Pde3d3N293bdlomw5ppimE2kAUZlpJIArbIDFCIu2FgRlYBEUrMPtDEimwi6YVJbUJJeYySkPbzL2pZTq2tna33Xufe+692/N6+mMvzE3qC+evw/nw+53f93sOEUJgvgghTFWVTYuiwS15XteS/Hx3GADS6Yn4ZNbsHR7WvuWpXKsQwl5wdj5QDSo1ZaVFJxqfr6tcuapSLgwVTO8IOMLG2FgSVy7dND498uONfwYzOxIJ3n1PICGEPFgVblm+YnHDK/u3Fnt9KihxgYJN4wQcYcJxDFiOjmyW4+DbrSO/dwzEbl2PN4tp0Cywoqq45cXmTXvq1i+XGXNDonmgRAYhDCCAEDYcx4Dt6LCcCVh2DqadQ/u5a8ZH758/9NfNRDMA0Jk2l698oPHx9bWyxDxwMe/UknzovNwPmamQqBcS84BRBZTKoMQFRiSsrauUH14RbQgG1RoAoIQQVlZadOLl154qZlQBowok5obEfDh88Bt8+N7ncEk+uJgblCigRAaFBEIYCKEACHY3rymJlHmOE0KY5FFZfcNz6yo9Xu/UnVEZlMj45EgbaqpWI5XQwUgeHGqDOjoIISAAyJxBKHkSnmmsrrp9a7xeikSDWx5ZvVimhIISBkoYTsXOIRyswLZt2/FD+/cYGBxEMhFHIjmKZGocmqYhrWXA0zlwPonCYoZH60rkRRF1i+RxK0uDhT4IALZjoe3LC4Adxs5nd0EIgUUlUZw+dRF+fwDBQBGKA1V4qNQPv9+PQCAAn8+H3XufxLrNFIqHVEq+fLnIMNOwbR2/XhhGaqQAr+9/dcZKeOPAWwuMP1ddXV2ILLYwaSXgVVEoWZZumzafNq6Fhbn5fznCxkw+JJ7W47ajVxIiYdXaYpxr68fBD1rw0t5mCCFw4M19cEnSVMvBEAKBEPwFgdmWy8vLMXhripZOmqPSRNbsGxtLrQmFKACBuvoo2r64iqMfH8aunbtxZ+Aatu9aCs7/RFq7ipEhjsyNSWS4iSw3kMuYKLlfQEsK5LLOdSkez7R2Xh5oqtugKEJYcKiBjVuj+Cp2Fp+d9MHlkhAMCxSEZDjCC8tms0mxbAFHTBno0vmEPj6qt9Ect8+cPNrTl8lqMG0Ow+IwLA2bd5Tg547j+OPGAHQrBcNKQTc1GFYappWGaXE4wgIAGLqD07Ghnhy3zxAhBFRVqXlsQ/i7F/Yvi1AyNwVA92/jqK7NhxAm7OksO8K8ayhH37099MvZ1EbO9W4KAJzr3T0d47GL7XcMw0rDsDToZgq6mULFMjJVnZWCaWcWwK78lDR6O3mMc70bmPd8Rcvd71TXqg1Ne8oiSh79T6vokw6OHeof6uvkscE7E/sWPF8zUlWlpug+V+zppkj1klpVKQi47trXkiZ6O7n+9bGhvtG/zYaZyma0ADhdLfOorD4YUp5we2i1WsDCAMA1Oz6Rc/oSY3prjttn7vUF/Av3AxdLDZ9NLQAAAABJRU5ErkJggg==
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAS2SURBVDiNbZV9TJVVGMB/5z3vvZfL5RVEuMgFg8jNBNbSdLVqpdPVCoemLVsJajPLdLZqw9TV+icsVktrUM1qGoqtZubClutjaqtMTcwRmJVJCSVe4d77cj/e+36c/hDdjM72/HPOzm/Pc/Y8vyOUUvx3CSGkYQTqSssL63NCvupx44JhgEQiPZhJ2j1//x3/1IylOpVS7pi7/wUahYHaiknFHY2Pz54y8+Yp/glF+aMnCk+5RKPDHDt8Ovv+2wd/+efcyENDQ2b3/wKFEOK668Mt02dUNTyzcWFJKM9AEz405ChO4Skbz8vieBbJpMlrzZ3nfzr+V/vvpwab1CjoCnDy9SUta5vqnpw9d7pfyiC6loMm/AghQYBSLp6XxfUsHC+N46aIxYf5av8Ju+Odw5vPnB5qAtAulzl95rWNs+ZO8+syF58MXQo9D79u4JcGuhZCl7lILYCm+THjNq3Nx+j+wfbV3BhpLCw0agE0IYSsmFTc8fSGBSVSCyC1ALoMoss8fLqBXzfw6Xn4ZBBNBNCEn/SIw5YXD9H2xg42v7qVoK+oJFKRu1MIIWWuIeetXVf3RHVtldS14CWYFkTXQ/i0ELoeAiXwcFHKxlM2zc99REtzG2VlZRQUFGDkFdPXf6Kor+/8cS1SXlh/0y1Vfk1oaEJeCYGGEBoo8HBQno3rZXn3zX08vHgllZWVABw58gMffPgekUl5sjRi1Ou5wUDNmdMXiUVdqmsmI9w0CvCUh+dlQQg8z8J2kxw9chLphamrqyeTybBqTQOFkSgLV45H+kJ8/YWYoueN8xf/eqqfX06cZVxBLzm5ilvvnMrtd0zD0y0APGUTiw+xe8cxdu38hFQqxfIVD1DfkEdRWZiskyDjJAgZTNAcx3LnLb4G5AhvtbbzyqZtRP/Mp3PvISwnjuXEsJw4r7d8SstLb5BOp2lcvoj5S/MJl+u4bgbXs7g8NJqZsAYVWRavuI71G5+ioKCAVatWc6r7HFknhuXE6Pz4W+bOWkRFRQUrH2/gvuUTCJfpOG56tCfTACSG7QtaOmn3RqMxyipzUIE/OXjoAIZhkIhnsZw4fX/08VuPTcOSZTz/wjpmzhGUlGnYzgiOm8RxU4AiPmyTSnqntMHBkc6uo39ZjptkwZJyWt/aBMCtt8zhxyO9bGvr4tWWNnbv+RDTPk7NTTlkXRPbHcF2R/CUA0DvCdO6eMHaJ+2s+r2/L7Fwdl3pRN2nSMRTCLuUeXULaHywiVda2shYFq1bN3D/o8U4bmo0sySKS++WtTzebD5zcrDfahJKKQwjUHvbXeH9azbeEFGepGNLll3tn2OaJq7rsmTZPTzybD5Sd3A9C0/ZVxlq68t/DHz3Rexu07S6NQDTtLp/Pn6x/fsDZ7OuMplYNcTevXtQSvHY6oeYvwKUlhgt8WrYsW+Gsz1dZrtpWt1j9FVeGdw0dZrRsGT1NZHDX2aIDkhmzJJUVfvGSNjKeGzf0jfQ22W2nzubXj9GX1cEawRqi8t87fctjUytnmYE8sdfDYsP2/R0mdae7QO9F/rthsuZjRHsVZtCyFxD3ltYFJgXzNWmGvkyDGDG3cF0yusdilqdKdP97P++gH8BTdBQ4IiYuvwAAAAASUVORK5CYII=
!usage
{{{[img[button-right.png]]}}}
[img[button-right.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIDwAACA8BoVenYQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAReSURBVDiNhZV9aFVlHMe/z8s5595z7rlnu3fb1TWZzsV1tsL5klFYW4jBFmblH6Fug5CsFKWkRRkSFImWhFRWCJUOhSjoxSlWWEaQkrJNm5tJ6sS39nJ3zt3Zvdu55+Xpj7sN3KS+8OP548fz4fl9n9/ze4gQAlNFCGG6rjTMLIutDGnS/Gg0XAIAw8Oj/WMZt/vWrfRh28q2CSH8aXunAvWYUl0+q/hQ0/N1ySVLk3K8yBjPCATCx+CgiTOnLuYOfPrrX/9cH1kzNGR33RFICCFz55XsWri4onHrtqcSWkQHJRIo2DhOIBAugiAHL3CQydh4/522vrPt11ovXehvEeOgSWDlvMSuzS0NW+qWL5QZC4PTECiRQQgDCCCEjyDIwQ8ceMEoPD8L18/ixPFzuU/e+2XP5YtDLQBAJ8pcuGROU+3yGpkzFRLT8sEjkLkOmengVANnKs533oDvU1AigRGOh+uS8oLFZY2xmF4NAJQQwspnFR96+fVVCUYVMKqAszA4i0DiOmSuQ+IRSCwMShR8fegUdmz7DiIgIIQCIHixZdmM0nL1ICGEUVVn9Y3PPZJUNS3vGZVBiQzGQpCoBolHwUgIhEqghCIWj6J57SbsfusYJuxSQhyrm6rmqTqr56VlsZWLHqiQKaH4+dh5dHVeh2EYMIwCFBQUwDCiUCMcWoQhpAFKmGL27Aqse2Yz9r67B+tfqoGAj+pFM+SZpfpKroaVe2LxCASA3st92LjhDRiGAcuyYFkW0uk0zFQKV/9OwbJSgGegsLAQlZWVyGZH8PlHH+DpZxMIR8agqCTJI1G5OOcOw/cd3Lu4EH+cPoV1a5uQSCSmNfxUNdQ/gUzGRtuX+1C7ikLTEeee5/iub+cbN3D/F3InBcKf9JPbw06/HzhJQjg6T9/A+nUb0dfXd1vJQ+YAhsxBmGYK6bSJV195E/F4HEeOfovjJ/eioVECIDBsugN8NOP2DA5ay4qKKGbMUrD7w62I6AoiugxV51A1Bi3CEZ/DUFZN8OP3l2GaJs6ea8dXh3di9YYwAuEhbbrIZoILvL9/pK3j9LXmuhWKsrS2AA8+WgJCJBBCQUAgICCEBz9wEQgHY1kPV3ov4bOD27Fms4ZAeACAnk7bSQ04RwgAVpGMntn9Re0CVQ1PPrd80wJCCAh4CAIXfpDDx2/3QsBD01YVhOZ9yzkBtr/Q3X6pO3M/EUJA15Xqh1aU/LBp232llPApwGDc9Dzwwp8myu/m4BKZvJR9O6/c/P0n6zHbdrooANi203W+PdV68kRvLucNI+el4bhWPjwLOS+/uv4I5s6XboOd+c3MdXfYrbbtdAFTxlfZ7PCOqhq9sXlLeakSov/ZKs5YgP17rt7s6bBbr/eOvjZtfE1I15Xq4ruk1iebS6vm1+iKUSjdlk+bLro7bOeb/Td7Bm64jRMnm9A04Phpmaqz+liR8nhYpVW6wUoAwE77/aPZoGdo0GnL2v7RO30B/wLrn/dftZcMEAAAAABJRU5ErkJggg==
iVBORw0KGgoAAAANSUhEUgAAAAUAAABGCAYAAAAEo14nAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKsAAACrABvY1x8QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABNSURBVDiNY7z19Ot/BjTAhC4wKjgqOCpIHUEWjOzGwMDA8v8/pjDLv39YVWIR/IdNOx1VYnUnNh9hVYlFFJeZFLpzQP2OPTaJ9zumKAACq0ckYXb5kQAAAABJRU5ErkJggg==
!usage
{{{
<<svgimg [[by-nd.svg]]>>
}}}
!preview
<<svgimg [[by-nd.svg]]>>
!link
http://creativecommons.org/licenses/by-nd/4.0/
!data
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="120"
height="42"
id="svg2759"
sodipodi:version="0.32"
inkscape:version="0.45+devel"
version="1.0"
sodipodi:docname="by-nd.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2761" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#8b8b8b"
borderopacity="1"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="179"
inkscape:cy="89.569904"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="120px"
height="42px"
inkscape:showpageshadow="false"
inkscape:window-width="1198"
inkscape:window-height="624"
inkscape:window-x="488"
inkscape:window-y="401" />
<metadata
id="metadata2764">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
transform="matrix(0.9937808,0,0,0.9936696,-177.69414,-223.30978)"
id="g78"
inkscape:export-filename="/mnt/hgfs/Bov/Documents/Work/2007/cc/identity/srr buttons/big/by-nd.png"
inkscape:export-xdpi="300.23013"
inkscape:export-ydpi="300.23013">
<path
id="path3817_6_"
nodetypes="ccccccc"
d="M 182.23535,225.17188 L 296.29931,225.375 C 297.89306,225.375 299.31689,225.13867 299.31689,228.55566 L 299.17724,266.12207 L 179.35693,266.12207 L 179.35693,228.41602 C 179.35693,226.73145 179.52002,225.17188 182.23535,225.17188 z"
style="fill:#aab2ab" />
<g
id="g5908_6_"
transform="matrix(0.872921,0,0,0.872921,50.12536,143.2144)">
<path
id="path5906_6_"
cx="296.35416"
ry="22.939548"
cy="264.3577"
type="arc"
rx="22.939548"
d="M 187.20946,115.90759 C 187.21504,124.58783 180.1816,131.62912 171.50138,131.6347 C 162.82116,131.64028 155.77932,124.60684 155.77428,115.92663 C 155.77428,115.91992 155.77428,115.9143 155.77428,115.90759 C 155.76924,107.22625 162.80213,100.18609 171.48236,100.18051 C 180.16368,100.17602 187.20442,107.20837 187.20946,115.88858 C 187.20946,115.89529 187.20946,115.90088 187.20946,115.90759 z"
style="fill:#ffffff" />
<g
id="g5706_6_"
transform="translate(-289.6157,99.0653)">
<path
id="path5708_6_"
d="M 473.88458,4.04068 C 477.36999,7.52551 479.11297,11.79349 479.11297,16.84229 C 479.11297,21.89225 477.40014,26.11432 473.9746,29.51081 C 470.33929,33.08625 466.04284,34.874 461.08517,34.874 C 456.18737,34.874 451.9653,33.10191 448.42004,29.55442 C 444.87423,26.00916 443.10162,21.77143 443.10162,16.84229 C 443.10162,11.91431 444.87423,7.64634 448.42004,4.04068 C 451.87524,0.55359 456.09732,-1.18939 461.08517,-1.18939 C 466.13342,-1.18939 470.39917,0.55359 473.88458,4.04068 z M 450.7666,6.38443 C 447.81982,9.36136 446.34704,12.84845 446.34704,16.84677 C 446.34704,20.84512 447.80529,24.302 450.72125,27.2185 C 453.63781,30.13391 457.10977,31.59274 461.1383,31.59274 C 465.16686,31.59274 468.66851,30.12051 471.64489,27.17376 C 474.47076,24.43734 475.88427,20.99615 475.88427,16.84676 C 475.88427,12.72872 474.44781,9.23381 471.57659,6.36202 C 468.70598,3.49248 465.22674,2.05605 461.1383,2.05605 C 457.04993,2.05606 453.59192,3.49921 450.7666,6.38443 z M 458.52106,15.08813 C 458.07077,14.10589 457.39673,13.61587 456.49784,13.61587 C 454.9087,13.61587 454.11439,14.68539 454.11439,16.8244 C 454.11439,18.96341 454.9087,20.03293 456.49784,20.03293 C 457.54719,20.03293 458.29676,19.5116 458.74647,18.46893 L 460.94926,19.64135 C 459.89933,21.50628 458.32417,22.44042 456.22377,22.44042 C 454.60384,22.44042 453.30611,21.94369 452.33168,20.95028 C 451.35561,19.95684 450.86897,18.58752 450.86897,16.84228 C 450.86897,15.12728 451.37126,13.76577 452.37645,12.75671 C 453.38161,11.74871 454.6335,11.2453 456.13426,11.2453 C 458.35438,11.2453 459.9441,12.11902 460.90507,13.86758 L 458.52106,15.08813 z M 468.8844,15.08813 C 468.43353,14.10589 467.77295,13.61587 466.90204,13.61587 C 465.28095,13.61587 464.46991,14.68539 464.46991,16.8244 C 464.46991,18.96341 465.28095,20.03293 466.90204,20.03293 C 467.95307,20.03293 468.68921,19.5116 469.10925,18.46893 L 471.36126,19.64135 C 470.31304,21.50628 468.74011,22.44042 466.64361,22.44042 C 465.02587,22.44042 463.73095,21.94369 462.75714,20.95028 C 461.78497,19.95684 461.29773,18.58752 461.29773,16.84228 C 461.29773,15.12728 461.79224,13.76577 462.78064,12.75671 C 463.76843,11.74871 465.02588,11.2453 466.55408,11.2453 C 468.77027,11.2453 470.35779,12.11902 471.31543,13.86758 L 468.8844,15.08813 z" />
</g>
</g>
<g
id="g85">
<circle
cx="242.56226"
cy="240.00684"
r="10.8064"
id="circle87"
sodipodi:cx="242.56226"
sodipodi:cy="240.00684"
sodipodi:rx="10.8064"
sodipodi:ry="10.8064"
style="fill:#ffffff" />
<g
id="g89">
<path
d="M 245.68994,236.87988 C 245.68994,236.46289 245.35205,236.12597 244.93603,236.12597 L 240.16357,236.12597 C 239.74755,236.12597 239.40966,236.46288 239.40966,236.87988 L 239.40966,241.65234 L 240.74071,241.65234 L 240.74071,247.30468 L 244.3579,247.30468 L 244.3579,241.65234 L 245.68993,241.65234 L 245.68993,236.87988 L 245.68994,236.87988 z"
id="path91" />
<circle
cx="242.5498"
cy="233.86523"
r="1.63232"
id="circle93"
sodipodi:cx="242.5498"
sodipodi:cy="233.86523"
sodipodi:rx="1.63232"
sodipodi:ry="1.63232" />
</g>
<path
clip-rule="evenodd"
d="M 242.53467,228.10059 C 239.30322,228.10059 236.56641,229.22754 234.32715,231.48438 C 232.0293,233.81739 230.88086,236.58008 230.88086,239.76856 C 230.88086,242.95704 232.0293,245.7002 234.32715,247.99512 C 236.625,250.29004 239.36133,251.4375 242.53467,251.4375 C 245.74756,251.4375 248.53272,250.28027 250.88819,247.96582 C 253.10889,245.76855 254.21827,243.03613 254.21827,239.76855 C 254.21827,236.50097 253.08936,233.74023 250.83057,231.48437 C 248.57178,229.22754 245.80615,228.10059 242.53467,228.10059 z M 242.56396,230.2002 C 245.2124,230.2002 247.46142,231.13379 249.31103,233.00098 C 251.18115,234.84766 252.11572,237.1045 252.11572,239.76856 C 252.11572,242.45215 251.20068,244.67969 249.36963,246.44922 C 247.4419,248.35449 245.17334,249.30762 242.56397,249.30762 C 239.9546,249.30762 237.70557,248.36426 235.81739,246.47852 C 233.92774,244.5918 232.98389,242.35547 232.98389,239.76856 C 232.98389,237.18165 233.93799,234.92579 235.84619,233.00098 C 237.67676,231.13379 239.9165,230.2002 242.56396,230.2002 z"
id="path95"
style="fill-rule:evenodd" />
</g>
<path
d="M 297.29639,224.73242 L 181.06739,224.73242 C 179.82081,224.73242 178.80616,225.74707 178.80616,226.99316 L 178.80616,266.48925 C 178.80616,266.77148 179.03516,266.99999 179.3169,266.99999 L 299.04639,266.99999 C 299.32813,266.99999 299.55713,266.77147 299.55713,266.48925 L 299.55713,226.99316 C 299.55713,225.74707 298.54297,224.73242 297.29639,224.73242 z M 181.06738,225.75391 L 297.29638,225.75391 C 297.97997,225.75391 298.53564,226.30957 298.53564,226.99317 C 298.53564,226.99317 298.53564,242.87598 298.53564,254.37208 L 215.46191,254.37208 C 212.41699,259.87794 206.55078,263.61622 199.81836,263.61622 C 193.08301,263.61622 187.21826,259.88087 184.17481,254.37208 L 179.82764,254.37208 C 179.82764,242.87599 179.82764,226.99317 179.82764,226.99317 C 179.82764,226.30957 180.38379,225.75391 181.06738,225.75391 z"
id="path97" />
<g
enable-background="new "
id="g99">
<path
d="M 239.17822,257.68848 C 239.49609,257.68848 239.78564,257.7168 240.04736,257.77246 C 240.30908,257.82812 240.53369,257.91992 240.72119,258.04785 C 240.90771,258.1748 241.05322,258.34473 241.15576,258.55566 C 241.2583,258.76757 241.31006,259.02832 241.31006,259.33984 C 241.31006,259.67578 241.23389,259.95507 241.08057,260.17968 C 240.92823,260.40331 240.70166,260.58691 240.40284,260.72948 C 240.81495,260.84764 241.12257,261.05468 241.32569,261.35057 C 241.52881,261.64646 241.63038,262.00291 241.63038,262.41991 C 241.63038,262.75585 241.56495,263.04686 241.43409,263.29296 C 241.30323,263.53906 241.12647,263.73925 240.90577,263.89452 C 240.68409,264.05077 240.43116,264.166 240.14796,264.24022 C 239.86378,264.31542 239.57276,264.35252 239.27296,264.35252 L 236.03663,264.35252 L 236.03663,257.68846 L 239.17822,257.68846 L 239.17822,257.68848 z M 238.99121,260.38379 C 239.25244,260.38379 239.46777,260.32227 239.63623,260.19727 C 239.8042,260.07325 239.88818,259.87207 239.88818,259.59278 C 239.88818,259.43751 239.85986,259.31055 239.8042,259.21094 C 239.74756,259.11133 239.67334,259.03418 239.57959,258.97852 C 239.48633,258.92188 239.37891,258.88379 239.25732,258.86133 C 239.13574,258.83985 239.00976,258.8291 238.8789,258.8291 L 237.50536,258.8291 L 237.50536,260.38379 L 238.99121,260.38379 z M 239.07666,263.21191 C 239.22021,263.21191 239.35693,263.19824 239.48828,263.16992 C 239.61865,263.1416 239.73486,263.0957 239.83447,263.03027 C 239.93408,262.96484 240.01318,262.87597 240.07275,262.76465 C 240.13232,262.65235 240.16162,262.50977 240.16162,262.33496 C 240.16162,261.99316 240.06494,261.74902 239.87158,261.60351 C 239.67822,261.45703 239.42285,261.38378 239.10498,261.38378 L 237.50537,261.38378 L 237.50537,263.2119 L 239.07666,263.2119 L 239.07666,263.21191 z"
id="path101"
style="fill:#ffffff" />
<path
d="M 241.88916,257.68848 L 243.53271,257.68848 L 245.09326,260.32032 L 246.64404,257.68848 L 248.27783,257.68848 L 245.8042,261.79493 L 245.8042,264.35255 L 244.33545,264.35255 L 244.33545,261.75782 L 241.88916,257.68848 z"
id="path103"
style="fill:#ffffff" />
</g>
<g
enable-background="new "
id="g105">
<path
d="M 265.27686,257.68848 L 268.06104,262.15918 L 268.07666,262.15918 L 268.07666,257.68848 L 269.45166,257.68848 L 269.45166,264.35254 L 267.98584,264.35254 L 265.2124,259.89063 L 265.19385,259.89063 L 265.19385,264.35254 L 263.81885,264.35254 L 263.81885,257.68848 L 265.27686,257.68848 z"
id="path107"
style="fill:#ffffff" />
<path
d="M 273.61377,257.68848 C 274.04443,257.68848 274.44385,257.75684 274.81494,257.89356 C 275.18603,258.03126 275.50635,258.23633 275.77783,258.50977 C 276.04834,258.78321 276.26025,259.12598 276.4126,259.53614 C 276.56592,259.94727 276.64209,260.42969 276.64209,260.98341 C 276.64209,261.46876 276.57959,261.917 276.45557,262.32716 C 276.33057,262.73829 276.14209,263.09278 275.89014,263.39161 C 275.63721,263.68946 275.32276,263.92481 274.9458,264.09571 C 274.56885,264.26759 274.12549,264.35255 273.61377,264.35255 L 270.73584,264.35255 L 270.73584,257.68849 L 273.61377,257.68849 L 273.61377,257.68848 z M 273.51123,263.11816 C 273.72314,263.11816 273.92822,263.08398 274.12744,263.01562 C 274.32666,262.94726 274.50439,262.83398 274.65967,262.67578 C 274.81494,262.5166 274.93994,262.31055 275.03369,262.05566 C 275.12646,261.80078 275.17334,261.49023 275.17334,261.12304 C 275.17334,260.7871 275.14111,260.48437 275.07568,260.21386 C 275.01025,259.94335 274.90283,259.71191 274.75341,259.51952 C 274.60399,259.32713 274.40673,259.17968 274.16064,259.07616 C 273.91455,258.9746 273.61084,258.92284 273.25048,258.92284 L 272.20458,258.92284 L 272.20458,263.11815 L 273.51123,263.11815 L 273.51123,263.11816 z"
id="path109"
style="fill:#ffffff" />
</g>
<g
id="g6501"
transform="matrix(0.624995,0,0,0.624995,-183.0107,316.9328)">
<path
id="path6503"
cx="475.97119"
ry="29.209877"
cy="252.08646"
type="arc"
rx="29.209877"
d="M 743.93005,-123.39972 C 743.93634,-113.98871 736.31128,-106.35272 726.89868,-106.34491 C 717.48767,-106.34021 709.85168,-113.96213 709.84387,-123.37628 C 709.84387,-123.38409 709.84387,-123.39346 709.84387,-123.39972 C 709.83764,-132.81229 717.46264,-140.44675 726.87524,-140.45456 C 736.28784,-140.46237 743.92224,-132.83728 743.93005,-123.42471 C 743.93005,-123.4169 743.93005,-123.40909 743.93005,-123.39972 z"
style="fill:#ffffff" />
<g
id="g6505"
transform="translate(-23.9521,-87.92102)">
<path
id="path6507"
d="M 750.57263,-54.14914 C 745.39917,-54.14914 741.02258,-52.34604 737.43976,-48.7366 C 733.76319,-45.00219 731.92566,-40.58343 731.92566,-35.4787 C 731.92566,-30.37552 733.76318,-25.98956 737.43976,-22.3161 C 741.11633,-18.64419 745.49292,-16.80823 750.57263,-16.80823 C 755.71179,-16.80823 760.16809,-18.66138 763.93835,-22.36298 C 767.48999,-25.88019 769.2666,-30.25211 769.2666,-35.4787 C 769.2666,-40.70844 767.45874,-45.12564 763.8446,-48.7366 C 760.23059,-52.34604 755.80554,-54.14914 750.57263,-54.14914 z M 750.61951,-50.79129 C 754.85547,-50.79129 758.45398,-49.29599 761.41492,-46.30691 C 764.40558,-43.3522 765.90088,-39.74435 765.90088,-35.47869 C 765.90088,-31.1849 764.43683,-27.62237 761.50708,-24.7911 C 758.42273,-21.74108 754.79297,-20.21764 750.61951,-20.21764 C 746.44294,-20.21764 742.84449,-21.72545 739.82257,-24.74578 C 736.80066,-27.76299 735.28973,-31.34115 735.28973,-35.47869 C 735.28973,-39.61935 736.81628,-43.22719 739.86944,-46.30691 C 742.79919,-49.29599 746.38196,-50.79129 750.61951,-50.79129 z" />
<g
id="g6509">
<path
id="path6511"
d="M 757.65088,-39.90375 L 744.07727,-39.90375 L 744.07727,-36.68964 L 757.65088,-36.68964 L 757.65088,-39.90375 z M 757.65088,-33.90369 L 744.07727,-33.90369 L 744.07727,-30.68961 L 757.65088,-30.68961 L 757.65088,-33.90369 z" />
</g>
</g>
</g>
</g>
</g>
</svg>
/***
|Name|Calculator|
|Version|1.3|
|Author|Rolf Lindén (rolind@utu.fi)|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer.|
|Description|Simulates the basic functionality of a handheld calculator using Javascript backend to do the actual heavylifting. Uses MathQuill and jQuery for the UI.|
!!!!!Revisions
<<<
20130906.1129 ''Version 1.3''
* Fixed fraction typing bug. Changed the functionality of other similar keys.
* Added keyboard support for calculator buttons.
20130905.0959 ''Version 1.2''
* Fixed mathquill selection bug.
20130829.1012 ''Version 1.1''
* Changed utf8 characters to their ascii representations to avoid server side character encoding issues.
20130822.1431 ''Version 1''
* Fixed large factorial hang up.
* Fixed button caption selection bug.
* Added debug output mode.
* Rudimentary handling for superscript exponents.
* Handling for infinite values.
20130404.0906 ''Version 0.03''
* Works with both old and new jQuery versions (attr / prop both supported).
* Adds 'attachables' and 'press' methods to the API to enable interaction with external modules.
20121212.1454 ''Version 0.02''
* Adds copy-paste to old inputs and outputs.
* Adds ans function and ans button.
* Adds real-time computation of input (feels better this way).
* No longer takes empty input.
<<<
!!!!!Code
***/
//{{{
/**
* Simple Offline Calculator
*
* Simulates the basic functionality of a handheld calculator using
* Javascript backend to do the actual heavylifting. Uses MathQuill and
* jQuery for the UI.
*
* Created by: E-Math -project ( http://emath.eu )
* @version 1.3
* @author Rolf Lindén (rolind@utu.fi)
*
* Copyright: Four Ferries oy
* http://fourferries.fi
* License: GNU AGPL
*/
(function ($) {
{ /** CSS & glyphs **/
var sCSS =
' .calculator {'
+' width: 270px;'
+' display:inline-block;'
+' background-color:#fcfcfc;'
+' padding:20px;'
+' }'
+' .lineId {'
+' float: left;'
+' text-align: right;'
+' color: blue;'
+' padding-left: 5px;'
+' padding-right: 5px;'
+' font-size: 10px;'
//+' width: 45px;'
+' }'
+' .calcBtn {'
+' width: 50px;'
+' margin: 2px;'
+' height: 30px;'
+' display: inline-block;'
+' /*background-color : #ccc;*/'
+' padding: 0px;'
+' -webkit-user-select: none;'
+' -moz-user-select: none;'
+' -khtml-user-select: none;'
+' -ms-user-select: none;'
+' vertical-align: text-top;'
+' display: inline-block;'
+' *display: inline;'
+' /*vertical-align: baseline;*/'
+' /*margin: 0 2px;*/'
+' outline: none;'
+' cursor: pointer;'
+' text-align: center;'
+' text-decoration: none;'
+' text-shadow: 0 1px 1px rgba(0,0,0,.3);'
+' -webkit-border-radius: 2px;'
+' border-radius: 2px;'
+' -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);'
+' box-shadow: 0 1px 2px rgba(0,0,0,.2);'
+' -webkit-user-select: none;'
+' -moz-user-select: none;'
+' -khtml-user-select: none;'
+' -ms-user-select: none;'
+' }'
+' .calcBtn:hover {'
+' text-decoration: none;'
+' }'
+' .calcBtn:active {'
+' position: relative;'
+' top: 1px;'
+' }'
+' span#in.mathquill-editable.hasCursor, span#in.mathquill-editable .hasCursor {'
+' -webkit-box-shadow: none;'
+' box-shadow: none;'
+' }'
+' span#in.mathquill-editable .cursor {'
+' border-left: 1px solid black;'
+' margin-right: -1px;'
+' position: relative;'
+' z-index: 1;'
+' }'
+' span#in.mathquill-rendered-math {'
+' border: 0px !important;'
+' box-shadow: 0 0 0px 0px white !important;'
+' width: 100%;'
+' }'
+' /* white */'
+' .white {'
+' color: #303030;'
+' border: solid 1px #b7b7b7;'
+' background: #fff;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ededed));'
+' background: -moz-linear-gradient(top, #fff, #ededed);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ffffff\', endColorstr=\'#ededed\');'
+' }'
+' .white:hover {'
+' background: #ededed;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));'
+' background: -moz-linear-gradient(top, #fff, #dcdcdc);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ffffff\', endColorstr=\'#dcdcdc\');'
+' }'
+' .white:active {'
+' color: #999;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));'
+' background: -moz-linear-gradient(top, #ededed, #fff);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ededed\', endColorstr=\'#ffffff\');'
+' }'
+' /* gray */'
+' .gray {'
+' color: #202020;'
+' border: solid 1px #a7a7a7;'
+' background: #eee;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#dcdcdc));'
+' background: -moz-linear-gradient(top, #eee, #dcdcdc);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#eeeeee\', endColorstr=\'#dcdcdc\');'
+' }'
+' .gray:hover {'
+' background: #ededed;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));'
+' background: -moz-linear-gradient(top, #fff, #dcdcdc);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ffffff\', endColorstr=\'#dcdcdc\');'
+' }'
+' .gray:active {'
+' color: #999;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));'
+' background: -moz-linear-gradient(top, #ededed, #fff);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ededed\', endColorstr=\'#ffffff\');'
+' }'
+' /* red */'
+' .red {'
+' color: #faddde;'
+' border: solid 1px #980c10;'
+' background: #d81b21;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));'
+' background: -moz-linear-gradient(top, #ed1c24, #aa1317);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#ed1c24\', endColorstr=\'#aa1317\');'
+' }'
+' .red:hover {'
+' background: #b61318;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));'
+' background: -moz-linear-gradient(top, #c9151b, #a11115);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#c9151b\', endColorstr=\'#a11115\');'
+' }'
+' .red:active {'
+' color: #de898c;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));'
+' background: -moz-linear-gradient(top, #aa1317, #ed1c24);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#aa1317\', endColorstr=\'#ed1c24\');'
+' }'
+' /* green */'
+' .green {'
+' color: #e8f0de;'
+' border: solid 1px #538312;'
+' background: #64991e;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e));'
+' background: -moz-linear-gradient(top, #7db72f, #4e7d0e);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#7db72f\', endColorstr=\'#4e7d0e\');'
+' }'
+' .green:hover {'
+' background: #538018;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#6b9d28), to(#436b0c));'
+' background: -moz-linear-gradient(top, #6b9d28, #436b0c);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#6b9d28\', endColorstr=\'#436b0c\');'
+' }'
+' .green:active {'
+' color: #a9c08c;'
+' background: -webkit-gradient(linear, left top, left bottom, from(#4e7d0e), to(#7db72f));'
+' background: -moz-linear-gradient(top, #4e7d0e, #7db72f);'
+' filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=\'#4e7d0e\', endColorstr=\'#7db72f\');'
+' }'
+' .enterBtn {'
+' height: 64px;'
+' margin-bottom: -34px;'
+' }'
+' .sqrtBtn {'
+' letter-spacing: -0.2em;'
+' }'
+' .SEcorner { border-radius: 2px 2px 15px 2px; }'
+' .SWcorner { border-radius: 2px 2px 2px 15px; }'
+' .NEcorner { border-radius: 2px 15px 2px 2px; }'
+' .NWcorner { border-radius: 15px 2px 2px 2px; }'
+' .zeroBtn {'
+' width: 104px;'
+' }'
+' .emptyContainer {'
+' /*background-color : inherit*/;'
+' height: 0px;'
+' z-index: -100;'
+' }'
+' .calcNumberBtn {'
+' background-color : #eee !important;'
+' }'
+' .clearBtn {'
+' background-color : #e88;'
+' }'
+' div.inOld span.mathquill-embedded-latex, div.outOld span.mathquill-rendered-math {'
+' cursor : pointer;'
+' }'
+' .calcInput {'
+' width : 100%;'
+' resize: none;'
+' background-color: #eff8ff;'
+' margin: 0px;'
+' border: none;'
+' padding-left:5px;'
+' font: 14px "Lucida Grande", "Trebuchet MS", Verdana, sans-serif;'
+' font-family: \'Junction\';'
+' font-weight: normal;'
+' line-height: 1.34em;'
+' }'
+' .inOld {'
+' background-color: #f8f8f8;'
+' width : 100%;'
+' resize: none;'
+' margin: 0px;'
+' border: none;'
+' padding-top: 5px;'
+' padding-bottom: 5px;'
+' padding-left: 5px;'
+' }'
+' .outOld {'
+' text-align: right;'
+' padding-right:10px;'
+' padding-top: 5px;'
+' padding-bottom: 5px;'
+' }'
+' .calcResult {'
+' text-align: right;'
+' padding-right:10px;'
+' }'
+' .inputDisplay {'
+' width: 264px;'
+' height: 125px;'
+' resize: vertical;'
+' overflow-x: hidden;'
+' overflow-y: auto;'
+' min-height: 50px;'
+' border: solid 1px #ccc;'
+' background-color: #fff;'
+' margin-left: 2px;'
+' margin-bottom: 2px;'
+' }';
}
{ /** Calculator functionality **/
{ /* Math library extensions */
/**
* Adds 10-base logarithm to Math library.
*/
Math.logTen = function(x) { return Math.log(x) * Math.LOG10E; }
/**
* Adds factorial to Math library.
*
* Implementation doesn't do memorization or any of the numerical
* accuracy improvements.
*/
Math.factorial = function(num) {
if ((typeof(num) === 'number') && (num >= 0)) {
if (num >= 1000) return(Number.POSITIVE_INFINITY); // Javascript's numeric capabilities stop much earlier than this, on the test bench the limit is 170.
//if ((n===+n) && (n!==(n|0))) return(undefined); // Not defined for decimals. Would require an implementation of the Gamma function.
var result = 1;
for (var i = 2; i <= num; i++) result *= i;
return(result);
} else return(undefined); // Unprocessed cases.
}
/**
* Adds hyperbolic sine to Math library.
*/
Math.sinh = function (aValue) { return (Math.pow(Math.E, aValue) - Math.pow(Math.E, -aValue)) / 2; }
/**
* Adds hyperbolic cosine to Math library.
*/
Math.cosh = function (aValue) { return (Math.pow(Math.E, aValue) + Math.pow(Math.E, -aValue)) / 2; }
Math.ans = function(n, randomName) {
return typeof randomName != 'undefined' ? parseFloat(randomName.data('ans-' + n)) : undefined;
}
Math.inp = function(n, randomName) {
return typeof randomName != 'undefined' ? randomName.data('inp-' + n) : undefined;
}
}
/**
* Converts the user input to valid evaluable Javascript.
*
* Taken from the ASCII Math Calculator project.
*/
var mathjs = function(st) {
st = st.replace(/\s/g,"");
if (st.indexOf("^-1")!=-1) {
st = st.replace(/sec\^-1/g,"Math.arcsec");
st = st.replace(/csc\^-1/g,"Math.arccsc");
st = st.replace(/cot\^-1/g,"Math.arccot");
st = st.replace(/sinh\^-1/g,"Math.arcsinh");
st = st.replace(/cosh\^-1/g,"Math.arccosh");
st = st.replace(/tanh\^-1/g,"Math.arctanh");
st = st.replace(/sech\^-1/g,"Math.arcsech");
st = st.replace(/csch\^-1/g,"Math.arccsch");
st = st.replace(/coth\^-1/g,"Math.arccoth");
}
st = st.replace(/pi/g,"Math.PI");
//st = st.replace(/([^a-zA-Z])e([^a-zA-Z])/g,"$1(Math.E)$2");
st = st.replace(/([0-9])([\(a-zA-Z])/g,"$1*$2");
st = st.replace(/\)([\(0-9a-zA-Z])/g,"\)*$1");
var i,j,k, ch, nested;
while ((i=st.indexOf("^"))!=-1) {
//find left argument
if (i==0) return "Error: missing argument";
j = i-1;
ch = st.charAt(j);
if (ch>="0" && ch<="9") {// look for (decimal) number
j--;
while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
if (ch==".") {
j--;
while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
}
} else if (ch==")") {// look for matching opening bracket and function name
nested = 1;
j--;
while (j>=0 && nested>0) {
ch = st.charAt(j);
if (ch=="(") nested--;
else if (ch==")") nested++;
j--;
}
while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z") j--;
} else if (ch>="a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
j--;
while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z") j--;
} else {
return "Error: incorrect syntax in " + st + " at position "+j;
}
//find right argument
if (i==st.length-1) return "Error: missing argument";
k = i+1;
ch = st.charAt(k);
if (ch>="0" && ch<="9" || ch=="-") {// look for signed (decimal) number
k++;
while (k<st.length && (ch=st.charAt(k))>="0" && ch<="9") k++;
if (ch==".") {
k++;
while (k<st.length && (ch=st.charAt(k))>="0" && ch<="9") k++;
}
} else if (ch=="(") {// look for matching closing bracket and function name
nested = 1;
k++;
while (k<st.length && nested>0) {
ch = st.charAt(k);
if (ch=="(") nested++;
else if (ch==")") nested--;
k++;
}
} else if (ch>="a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
k++;
while (k<st.length && (ch=st.charAt(k))>="a" && ch<="z" || ch>="A" && ch<="Z") k++;
} else {
return "Error: incorrect syntax in "+st+" at position "+k;
}
st = st.slice(0,j+1)+"Math.pow("+st.slice(j+1,i)+","+st.slice(i+1,k)+")"+
st.slice(k);
}
while ((i = st.indexOf("!"))!=-1) {
//find left argument
if (i == 0) return "Error: missing argument";
j = i - 1;
ch = st.charAt(j);
if (ch >= "0" && ch <= "9") {// look for (decimal) number
j--;
while (j >= 0 && (ch = st.charAt(j)) >= "0" && ch <= "9") j--;
if (ch == ".") {
j--;
while (j >= 0 && (ch = st.charAt(j)) >= "0" && ch <= "9") j--;
}
} else if (ch == ")") {// look for matching opening bracket and function name
nested = 1;
j--;
while (j >= 0 && nested > 0) {
ch = st.charAt(j);
if (ch == "(") nested--;
else if (ch == ")") nested++;
j--;
}
while (j >= 0 && (ch = st.charAt(j)) >= "a" && ch <= "z" || ch >= "A" && ch <= "Z") j--;
} else if (ch >= "a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
j--;
while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z") j--;
} else {
return "Error: incorrect syntax in "+st+" at position "+j;
}
st = st.slice(0,j+1)+"Math.factorial("+st.slice(j+1,i)+")"+st.slice(i+1);
}
return st;
}
/**
* Converts the given Latex expression to a Javascript expression.
*
* expression : Expression to be interpreted.
**/
var latexeval = function(place, expression, parseOnly) {
// Simple evaluator for math expressions. Converts LaTeX expression (without variables) to Javascript expression
// and tries to evaluate it to a number.
expression = '' + expression;
var randomName = 'r' + Math.ceil(Math.random() * 10000000);
Math[randomName] = place;
// Functions that can be nested, should be replaced repeatedly from innermost to the outermost.
var latexrep = [
[/((?:[\-+]?[0-9]+)|(?:\\left\([^\(\)]+\\right\)))!/ig, 'factorial($1)'],
[/\\sqrt{([^{}]+)}/ig, 'sqrt($1)'],
[/\\frac{([^{}]+)}{([^{}]+)}/ig, '(($1)/($2))'],
[/\\left\|([^\|]*)\\right\|/g, 'abs($1)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\^((?:[\-+]?[0-9\.]+)|(?:{[^{}]+}))/ig, 'pow($1, $2)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2070/ig, 'pow($1, 0)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u00B9/ig, 'pow($1, 1)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u00B2/ig, 'pow($1, 2)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u00B3/ig, 'pow($1, 3)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2074/ig, 'pow($1, 4)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2075/ig, 'pow($1, 5)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2076/ig, 'pow($1, 6)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2077/ig, 'pow($1, 7)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2078/ig, 'pow($1, 8)'],
[/((?:[\-+]?[0-9\.]+|\\pi|\\exp1)|(?:\\left\([^\(\)]+\\right\)))\u2079/ig, 'pow($1, 9)']
];
// Some LaTeX-markings need to be replaced only once.
var reponce = [
[/\\sin\^{-1}|\\arcsin|\\asin/ig, 'asin'], // Replace arcsin
[/\\cos\^{-1}|\\arccos|\\acos/ig, 'acos'], // Replace arccos
[/\\tan\^{-1}|\\arctan|\\atan/ig, 'atan'], // Replace arctan
//[/(?:\\inp|inp|\\text{inp})\\left\(([0-9]+)\\right\)/ig, 'inp($1, ' + randomName + ')'], // Replace ans
[/(?:\\ans|ans|\\text{ans})\\left\(([0-9]+)\\right\)/ig, 'ans($1, ' + randomName + ')'], // Replace ans
[/\\sin/ig, 'sin'], // Replace sin
[/\\cos/ig, 'cos'], // Replace cos
[/\\tan/ig, 'tan'], // Replace tan
[/\\ln/ig, 'log'], // Replace ln
[/\\log/ig, 'logTen'], // Replace log
[/\\pi/ig, 'PI'], // Replace PI
[/\\left\(/ig, '('], // Replace left parenthesis )
[/\\right\)/ig, ')'], // Replace right parenthesis
[/(sin|cos|tan)\(([^\^\)]+)\^{\\circ}/ig, '$1($2*PI/180'], // Replace degrees with radians inside sin, cos and tan
[/{/ig, '('], // Replace left bracket
[/}/ig, ')'], // Replace right bracket
[/\)\(/ig, ')*('], // Add times between ending and starting parenthesis )
[/\\cdot/ig, '*'], // Replace cdot with times
[/\\exp1/ig, 'exp(1)'], // Replace Neper's number
//[/([0-9]+)PI/ig, '$1*PI']
]
var oldexpr = '';
/*
* Commas should be replaced from the original input before
* any of the power functions (or other functions containing
* commas as separators) are replaced.
*/
expression = expression.replace(/,/ig, '.');
expression = expression.replace(/\\mathrm{e}|\\e|\\text{e}/ig, '\\exp1');
while (oldexpr !== expression) {
// Replace strings as long as the expression keeps changing.
oldexpr = expression;
for (var i = 0; i < latexrep.length; i++){
expression = expression.replace(latexrep[i][0], latexrep[i][1]);
}
}
for (var i = 0; i < reponce.length; i++){
expression = expression.replace(reponce[i][0], reponce[i][1]);
}
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig;
var valid = true;
expression = expression.replace(reg, function(word){
if (Math.hasOwnProperty(word)) {
return 'Math.' + word;
} else if (
(word.toLowerCase() == 'x') ||
(word.toLowerCase() == 'y') ||
(word.toLowerCase() == 'z') ||
(word.toLowerCase() == 't')
) return word;
else {
valid = false;
return word;
}
});
if (!valid){
throw 'Invalidexpression1';
} else {
try {
expression = mathjs(expression);
if (parseOnly) return expression;
var s = (new Function('return ('+expression+')'))();
delete Math[randomName];
return s;
} catch (err) {
throw 'Invalidexpression2';
}
}
}
/**
* Splits the output into lines, processes the output using eval and
* returns the result in element defined by the output ID.
*
* Derived from the ASCII Math Calculator project.
**/
var calculate = function(place, inputId, outputId) {
var str = pruneStr(place.find('#' + inputId).mathquill('latex'));
var err = "";
var str2 = str;
try {
var res = latexeval(place, str2);
} catch(e) {
err = "syntax incomplete";
}
if (!isNaN(res) && res!="Infinity")
str2 = (Math.abs(res-Math.round(res*1000000)/1000000)<1e-15?Math.round(res*1000000)/1000000:res)+err;
else if ( res == "Infinity" ) str2 = '\\text{Big enough to be numerically } \\infty \\text{.}';
else if (str2!='') str2 = "undefined";
place.find('#' + outputId).mathquill('revert').empty().html(str2).mathquill();
}
var pruneStr = function(str) {
return( str
.replace(/\\:/ig, '')
);
}
var copyToCurrent = function(place, from) {
var str = from.mathquill('latex');
var str = str.replace(/\\:/ig, '').replace(/\²/ig, '^2');
place.find('#in').mathquill('write', str).focus();
}
/**
* Inserts the given string to the input's cursor location.
*
* st: String-to-be-inserted.
* diff: Cursor movement after insertion. Positive goes right and
* negative to left.
*/
var insert = function(place, st, diff){
if (st == "@enterkey") {
// Check that input isn't empty.
var elemIn = place.find('span#in');
if (pruneStr(elemIn.mathquill('latex')) != '') {
calculate(place, 'in', 'out');
var elemOut = place.find('span#out');
var idNum = place.find('div.inOld').length;
var ansCount = place.data('ansCount');
place.find('div#inCurrent').before('<div class="inOld">' + /*'<span class="lineId">inp(' + ansCount + ') := </span>' + */'<span id="in-' + idNum + '" class=\"mathquill-embedded-latex\">' + pruneStr(elemIn.mathquill('latex')) + '</span></div>');
place.find('div#inCurrent').before('<div class="outOld"><span class="lineId">ans(' + ansCount + ') := </span><span id="out-' + idNum + '">' + pruneStr(elemOut.mathquill('latex')) + '</span></div>');
clearInput(place, false);
place.find('span#in-' + idNum).mathquill().click(function() { copyToCurrent(place, $(this)); });
place.find('span#out-' + idNum).mathquill().click(function() { copyToCurrent(place, $(this)); });
place.data('inp-' + ansCount, pruneStr(place.find('span#in-' + idNum).mathquill('latex')));
place.data('ans-' + ansCount, pruneStr(place.find('span#out-' + idNum).mathquill('latex')));
place.data('ansCount', ++ansCount);
}
}
else {
{
// Get cursor for the input element.
var $math_box = place.find('#in');
var data = $math_box.data('[[mathquill internal data]]');
var block = data && data.block;
var cursor = block && block.cursor;
var latex = cursor.selection ? cursor.selection.latex() : '';
// The suffix notation cases.
if (st == '\\frac{%1}{}') {
if (latex == '' && cursor.prev) latex = cursor.prev.latex();
cursor.backspace();
} else {
if (latex != '') {
if ((st == '%1!') || (st == '%1^2') || (st == '%1^'))
latex = '\\left(' + latex + '\\right)';
diff = (st == '%1^') ? -1 : 0;
}
}
if (st.length === 1) {
cursor.write(st);
place.find('#in').focus();
}
else place.find('#in').mathquill('write', st.replace('%1', latex)).focus();
// Move the cursor if needed.
if (diff != 0){
if (diff < 0) for (var i = 0; i < -1 * diff; i++) cursor.moveLeft();
else for (var j = 0; i < diff; i++) cursor.moveRight();
}
}
calculate(place, 'in','out');
}
if (typeof(place.find(".inputDisplay").prop) === "undefined") // .prop() doesn't exist in this version of jQuery.
place.find(".inputDisplay").animate({ scrollTop: place.find(".inputDisplay").attr("scrollHeight") }, 100);
else
place.find(".inputDisplay").animate({ scrollTop: place.find(".inputDisplay").prop("scrollHeight") }, 100);
}
/**
* Added by Rolf Lindén 20121120.1659
*/
var keyUpFunction = function(place) {
calculate(place, 'in','out');
}
/**
* Clears the input field.
**/
var clearInput = function(place, allowAll){
if ((pruneStr(place.find('#in').mathquill('latex')) == '') && (allowAll)) {
place.find('.inOld, .outOld').remove();
} else {
place.find('#out').mathquill('latex', '');
place.find('#in').mathquill('latex', '').focus();
}
}
/**
* Initialization function.
**/
var init = function (place, params){
// Checks if editor's CSS information is already written to document's head.
if ($('head style#calculatorstyle').length == 0){
$('head').append('<style id="calculatorstyle" type="text/css">' + sCSS + '</style>');
}
/*
* Layout of the calculator.
* Loosely based on the calculator template from ASCII Math Calculator project.
*/
var calcstr =
"<div class=\"inputDisplay\">" +
"<div class=\"calcInput\" id=\"inCurrent\"><span id=\"in\"></span></div>" +
"<div class=\"calcResult\" id=\"outCurrent\"><span id=\"out\"></span></div>" +
"</div>" +
"<button id=\"piBtn\" class=\"gray calcBtn \">π</button>" +
"<button id=\"arcsinBtn\" class=\"gray calcBtn\">sin<sup>-1</sup></button>" +
"<button id=\"arccosBtn\" class=\"gray calcBtn\">cos<sup>-1</sup></button>" +
"<button id=\"arctanBtn\" class=\"gray calcBtn\">tan<sup>-1</sup></button>" +
"<button id=\"clearBtn\" class=\"red calcBtn clearBtn\">C/CE </button><br/>" +
"<button id=\"expBtn\" class=\"gray calcBtn\">e</button>" +
"<button id=\"sinBtn\" class=\"gray calcBtn\">sin</button>" +
"<button id=\"cosBtn\" class=\"gray calcBtn\">cos</button>" +
"<button id=\"tanBtn\" class=\"gray calcBtn\">tan</button>" +
"<button id=\"divBtn\" class=\"gray calcBtn\">÷</button><br/>" +
"<button id=\"lnBtn\" class=\"gray calcBtn\">ln</button>" +
"<button id=\"logBtn\" class=\"gray calcBtn\">log</button>" +
"<button id=\"leftParenBtn\" class=\"gray calcBtn\">( )</button>" +
"<button id=\"absBtn\" class=\"gray calcBtn\">| |</button>" +
"<button id=\"prodBtn\" class=\"gray calcBtn\">⨯</button><br/>" +
"<button id=\"powBtn\" class=\"gray calcBtn\">x<sup>y</sup></button>" +
"<button id=\"b7\" class=\"white calcBtn calcNumberBtn\">7</button>" +
"<button id=\"b8\" class=\"white calcBtn calcNumberBtn\">8</button>" +
"<button id=\"b9\" class=\"white calcBtn calcNumberBtn\">9</button>" +
"<button id=\"subBtn\" class=\"gray calcBtn\">−</button><br/>" +
"<button id=\"quadBtn\" class=\"gray calcBtn\">x<sup>2</sup></button>" +
"<button id=\"b4\" class=\"white calcBtn calcNumberBtn\">4</button>" +
"<button id=\"b5\" class=\"white calcBtn calcNumberBtn\">5</button>" +
"<button id=\"b6\" class=\"white calcBtn calcNumberBtn\">6</button>" +
"<button id=\"addBtn\" class=\"gray calcBtn\">+</button><br/>" +
"<button id=\"sqrtBtn\" class=\"gray calcBtn sqrtBtn\">√¯</button>" +
"<button id=\"b1\" class=\"white calcBtn calcNumberBtn\">1</button>" +
"<button id=\"b2\" class=\"white calcBtn calcNumberBtn\">2</button>" +
"<button id=\"b3\" class=\"white calcBtn calcNumberBtn\">3</button>" +
"<button id=\"enterBtn\" class=\"gray calcBtn SEcorner green enterBtn\">⏎</button><br />" +
"<button id=\"factorialBtn\" class=\"gray calcBtn SWcorner\">n!</button>" +
"<button id=\"b0\" class=\"white calcBtn calcNumberBtn\">0</button>" +
"<button id=\"decimalBtn\" class=\"gray calcBtn\">,</button>" +
"<button id=\"ansBtn\" class=\"gray calcBtn\">Ans</button>";
var $this = $(place).addClass('calculator').html(calcstr);
{ // Click handlers.
$this.find('button#piBtn').click(function() { insert($this, '\\pi', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#expBtn').click(function() { insert($this, '\\e', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#clearBtn').click(function() { clearInput($this, true); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#powBtn').click(function() { insert($this, '^', 0/*'%1^', -1*/); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#quadBtn').click(function() { insert($this, '%1^2', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); })
$this.find('button#decimalBtn').click(function() { insert($this, '.', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#enterBtn').click(function() { insert($this, '@enterkey', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#addBtn').click(function() { insert($this, '+', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#subBtn').click(function() { insert($this, '-', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#divBtn').click(function() { insert($this, '/', 0/*'\\frac{%1}{}', -1*/); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#sqrtBtn').click(function() { insert($this, '\\sqrt{%1}', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#logBtn').click(function() { insert($this, '\\log\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#ansBtn').click(function() { insert($this, '\\ans\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#lnBtn').click(function() { insert($this, '\\ln\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#arcsinBtn').click(function() { insert($this, '\\sin^{-1}\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#arccosBtn').click(function() { insert($this, '\\cos^{-1}\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#arctanBtn').click(function() { insert($this, '\\tan^{-1}\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#sinBtn').click(function() { insert($this, '\\sin\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#cosBtn').click(function() { insert($this, '\\cos\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#tanBtn').click(function() { insert($this, '\\tan\\left(%1', -1); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#prodBtn').click(function() { insert($this, '*', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#leftParenBtn').click(function() { insert($this, '(', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#absBtn').click(function() { insert($this, '|', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#factorialBtn').click(function() { insert($this, '!', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b0').click(function() { insert($this, '0', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b1').click(function() { insert($this, '1', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b2').click(function() { insert($this, '2', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b3').click(function() { insert($this, '3', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b4').click(function() { insert($this, '4', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b5').click(function() { insert($this, '5', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b6').click(function() { insert($this, '6', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b7').click(function() { insert($this, '7', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b8').click(function() { insert($this, '8', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
$this.find('button#b9').click(function() { insert($this, '9', 0); $this.trigger('calculator_press', $.extend({ senderID: $this.attr('id'), buttonID : this.id }, $(this).parent().data('params')) ); });
}
{ // Key bindings.
$this.find('button').keypress(
function(e) {
var c = String.fromCharCode(e.which);
switch (c) {
case '0' : $this.find('button#b0').click(); break;
case '1' : $this.find('button#b1').click(); break;
case '2' : $this.find('button#b2').click(); break;
case '3' : $this.find('button#b3').click(); break;
case '4' : $this.find('button#b4').click(); break;
case '5' : $this.find('button#b5').click(); break;
case '6' : $this.find('button#b6').click(); break;
case '7' : $this.find('button#b7').click(); break;
case '8' : $this.find('button#b8').click(); break;
case '9' : $this.find('button#b9').click(); break;
case 'e' : $this.find('button#expBtn').click(); break;
case '²' : $this.find('button#quadBtn').click(); break;
case '/' : $this.find('button#divBtn').click(); break;
case 'c' : $this.find('button#clearBtn').click(); break;
case ',' : $this.find('button#decimalBtn').click(); break;
case '*' : $this.find('button#prodBtn').click(); break;
case '-' : $this.find('button#subBtn').click(); break;
case '+' : $this.find('button#addBtn').click(); break;
case '(' : $this.find('button#leftParenBtn').click(); break;
case '|' : $this.find('button#absBtn').click(); break;
case '!' : $this.find('button#factorialBtn').click(); break;
}
}
)
.keydown(
function(e) {
var $math_box = place.find('#in');
var data = $math_box.data('[[mathquill internal data]]');
var block = data && data.block;
var cursor = block && block.cursor;
e.ctrlKey = e.ctrlKey || e.metaKey;
switch ((e.originalEvent && e.originalEvent.keyIdentifier) || e.which) {
case 8: //backspace
case 'Backspace':
case 'U+0008':
if (e.ctrlKey)
while (cursor.prev || cursor.selection)
cursor.backspace();
else
cursor.backspace();
break;
}
}
);
}
$this.data('ansCount', 0);
$this.data('buttonIDs', params.buttonIDs);
$this.find('span#in').mathquill(params.editable ? "editable" : undefined).focus().keyup(function(e) {
if (e.keyCode == '13' && !(e.shiftKey || e.ctrlKey || e.altKey))
$this.find('button#enterBtn').click();
else keyUpFunction($this);
});
// Announce existence.
var announced = { senderID: $this.attr('id'), fnName: 'calculator' };
$this.trigger('announce', announced);
}
}
{ /** jQuery Plugin interface **/
var methods = {
'init' : function(params) {
// call handler.
params = $.extend( {
editable: true, // By default, the current line is editable.
buttonIDs: [
'piBtn', 'expBtn', 'clearBtn', 'powBtn', 'quadBtn',
'decimalBtn', 'enterBtn', 'addBtn', 'subBtn', 'divBtn',
'sqrtBtn', 'logBtn', 'ansBtn', 'lnBtn', 'arcsinBtn',
'arcCosBtn', 'arctanBtn', 'sinBtn', 'cosBtn', 'tanBtn',
'prodBtn', 'leftParenBtn', 'absBtn', 'factorialBtn',
'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9'
],
}, params);
return this.each( function() {
init($(this), params);
});
},
'parse' : function(params) {
return latexeval($(this), params, true);
},
'calculate' : function(params) {
return latexeval($(this), params, false);
},
'attachables' : function(params) {
return [
{
'eventType' : 'calculator_press',
'action' : 'press'
}
];
},
'unittest' : function(params) {
tests = [
{ method: 'calculate', clause: '5!', check: function(ans) { return ans == '120'; }},
{ method: 'calculate', clause: '1+1', check: function(ans) { return ans == '2'; }},
{ method: 'calculate', clause: '1+2+3', check: function(ans) { return ans == '6'; }},
{ method: 'calculate', clause: '\\left|-8\\right|', check: function(ans) { return ans == '8'; }},
{ method: 'calculate', clause: '1-(3*4)', check: function(ans) { return ans == '-11'; }},
{ method: 'calculate', clause: '\\frac{8}{12}', check: function(ans) { return Math.abs(0.66666666 - ans) < 0.00001; }},
{ method: 'calculate', clause: '2^2^2', check: function(ans) { return ans == '16'; }},
{ method: 'calculate', clause: '\\sin\\left(\\pi\\right)', check: function(ans) { return Math.abs(0 - ans) < 0.00001; }},
{ method: 'calculate', clause: '\\sin\\left(\\arccos\\left( 1 \\right)\\right)', check: function(ans) { return Math.abs(0 - ans) < 0.00001; }},
];
var total = 0;
var passed = 0;
for (i in tests) {
var result = methods[tests[i].method](tests[i].clause);
var outcome = (result == 'Invalidexpression' ? false : tests[i].check(result));
if (!outcome) console.error('Unit test failed for "' + tests[i].clause + '":\n\tGot "' + result + '".')
passed += outcome;
++total;
}
if (passed == total) {
return true;
} else {
return false;
}
},
'press' : function(params) {
return this.each( function() {
var buttonIDs = $(this).data('buttonIDs');
if (buttonIDs.indexOf(params.buttonID) >= 0) {
$(this).data('params', params);
$(this).find('button#' + params.buttonID).click();
$(this).removeData('params');
}
else console.error('Calculator: Invalid button ID "' + params.buttonID + '".');
});
}
}
$.fn.calculator = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.calculator' );
return false;
}
}
}
})(jQuery)
//}}}
//{{{
// Added so it can be used without TiddlyWiki.
if (typeof config == 'undefined') {
var config = new Object();
config.macros = new Object();
}
config.macros.calculator = {
/******************************
* Show calculator
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var calculatordiv = '{{calculator{\n}}}';
wikify(calculatordiv, place, null, tiddler);
jQuery(place).find('.calculator').last().calculator('init');
}
}
//}}}
!usage
{{{[img[calculator.png]]}}}
[img[calculator.png]]
!notes
Icon for calculator app
!type
image/png
!file
!url
!data
data:image/png;base64,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
{{cblogo{
{{caption{
Content}}}<<svgimg [[by-nd.svg]] [[logo]]>>}}}
{{eulogo{
{{caption{
Software}}}<<svgimg [[agpl-logo.svg]] [[logo]]>>}}}
<html><div style="clear: both;"></div></html>
{{disclaimer{
{{cblogo{[img[CB_logo-300.png]]}}}{{eulogo{[img[EU_with_references.png]]}}} The contents of the website reflect the authors' views. The Managing Authority of the Central Baltic INTERREG IVA Programme cannot be held liable for the information published by the project partners.}}}
/***
|Name|Chart.js|
|Version|1.1|
|Author|Rolf Lindén (rolind@utu.fi)|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, calculator.js.|
|Description|Chart addon for E-Math table plugin.|
!!!!!Revisions
<<<
20130812.1127 ''Version 1.1''
* Fixed label color association bug.
20130611.1539 ''Version 1.00''
* First release.
<<<
!!!!!Code
***/
//{{{
/** chart.js
*
* Chart plotter.
* Created by: E-Math -project ( http://emath.eu )
* Rolf Lindén
* Copyright: Four Ferries oy
* http://fourferries.fi
* License: GNU AGPL
*/
(function ($) {
{ /** CSS & glyphs **/
var glyphs =
'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' +
'QmCC';
var chartCSS = '.chart {'
+ ' display: table;'
+ ' margin-left: auto;'
+ ' margin-right: auto;'
+ '}'
+'.frame {'
+ ' width: 100%;'
+ ' height: 100%;'
+ ' background-color: white;'
+ ' border: 1px solid gray;'
+ ' margin: 8px;'
+ ' padding: 0px;'
+ ' padding-bottom: 30px;'
+ '}'
+ '.legend {'
+ ' z-index: 10;'
+ ' text-align: left;'
+ ' position: absolute;'
+ ' bottom: -7px;'
+ ' right: 8px;'
+ ' background-color: rgba(255, 255, 255, 0.75);'
+ ' border: 1px solid gray;'
+ ' padding: 8px;'
+ ' border-radius: 2px;'
//+ ' -webkit-transition: all 0.5s ease;'
//+ ' -moz-transition: all 0.5s ease;'
//+ ' -o-transition: all 0.5s ease;'
//+ ' transition: all 0.5s ease;'
+ '}'
+ '.legend:empty { display: none; }'
+ '.legendleft {'
+ ' left: 8px;'
+ ' right: auto;'
//+ ' -webkit-transition: all 0.5s ease;'
//+ ' -moz-transition: all 0.5s ease;'
//+ ' -o-transition: all 0.5s ease;'
//+ ' transition: all 0.5s ease;'
+'}'
// Chart type list.
+ '.emtabletoolbar .emtablechartlistwrapper {position: absolute; right: -0.35em; top: -0.3em;}'
+' .emtabletoolbar .emtablechartlistwrapper ul {position: absolute; left: 0; top: 0; padding: 0; margin: 0; list-style: none; border: 1px solid #777; border-left: none; border-radius: 0 0.3em 0.3em 0; overflow: hidden;}'
+ '.emtabletoolbar .emtablechartlistwrapper ul li {font-size: 80%; margin: 0; padding: 0; padding-right: 10px;'
+ 'background: rgb(255,255,255); /* Old browsers */'
+ 'background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%); /* FF3.6+ */'
+' background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1))); /* Chrome,Safari4+ */'
+ 'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Chrome10+,Safari5.1+ */'
+ 'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Opera 11.10+ */'
+ 'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* IE10+ */'
+ 'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* W3C */'
+ 'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffff\', endColorstr=\'#e5e5e5\',GradientType=0 ); /* IE6-9 */}'
+ '.emtabletoolbar .emtablechartlistwrapper ul li a {vertical-align: middle; margin: 0; padding: 0.2em; display: inline-block; width: 20px; height: 20px; margin-right: 5px;}'
+ '.emathtable .emtablechartlistwrapper a[ctype] span {display: inline-block; width: 20px; height: 20px; padding: 0; margin: 0;}'
+ 'div.emtabletoolbar div.emtablechartlistwrapper ul li a.selected {border: 1px solid red; }'
+ '.emathtable a[ctype="scatter"] span { background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;background-position: 0px 0px !important; }'
+ '.emathtable a[ctype="line"] span { background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;background-position: -20px 0px !important; }'
+ '.emathtable a[ctype="spline"] span { background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;background-position: -40px 0px !important; }'
+ '.emathtable a[ctype="bar"] span { background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;background-position: -60px 0px !important; }'
+ '.emathtable a[ctype="pie"] span { background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;background-position: -80px 0px !important; }'
+ '.emathtable a.emtablechartglyph span {'
+ ' background: transparent url("data:image/png;base64,' + glyphs + '") no-repeat !important;'
+ ' background-position: -80px 0px !important;'
+ '}'
+ '.legend li { list-style-type: none; }'
+ '.colorbox {'
+ ' width: 8px;'
+ ' height: 8px;'
+ ' border-radius: 8px;'
+ ' border: 1px solid gray;'
+ ' display: inline-block;'
+ ' vertical-align: middle;'
+ '}';
}
{ /** Chart plotter **/
function Chart(params) {
this.params = params;
for (var item in params)
this[item] = params[item];
// Checks if editor's CSS information is already written to document's head.
if ($('head style#chartstyle').length == 0) {
$('head').append('<style id="chartstyle" type="text/css">' + chartCSS + '</style>');
}
this.place.empty();
var boxnum = 0;
while ($( '#chartframe-' + boxnum ).length > 0) ++boxnum;
this.boxnum = boxnum;
this.place.append('<div id="chartframe-' + this.boxnum + '" class="frame" style="width: ' + this.width + '; height: ' + this.height + '"></div>')
$('#chartframe-' + this.boxnum).data('params', params);
this.maxWidth = this.place.width();
this.maxHeight = this.place.height();
if (this.showPlot) this.plot();
}
/** unique()
*
* Derives a (sorted) array of unique items from the data array given as a parameter.
*
* @param data : Data to be processed.
* @param fCompare : Compare function, as defined for array.sort(). If undefined, the default comparison is used.
*/
function unique(data, fCompare) {
var sorted = data.sort(fCompare);
var uniqueArr = new Array();
for (var i = 0; i < sorted.length; ++i)
if ( i == 0 || (fCompare(sorted[i - 1], sorted[i]) != 0) ) uniqueArr.push(sorted[i]);
return uniqueArr;
}
/**
* Converts HSV to RGB value.
*
* @param {Integer} h Hue as a value between 0 - 360 degrees
* @param {Integer} s Saturation as a value between 0 - 100 %
* @param {Integer} v Value as a value between 0 - 100 %
* @returns {Array} The RGB values EG: [r,g,b], [255,255,255]
*/
function hsv2rgb(h,s,v) {
s = s / 100;
v = v / 100;
var hi = Math.floor((h/60) % 6);
var f = (h / 60) - hi;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
var rgb = [];
switch (hi) {
case 0: rgb = [v,t,p]; break;
case 1: rgb = [q,v,p]; break;
case 2: rgb = [p,v,t]; break;
case 3: rgb = [p,q,v]; break;
case 4: rgb = [t,p,v]; break;
case 5: rgb = [v,p,q]; break;
}
var r = Math.min(255, Math.round(rgb[0] * 256)),
g = Math.min(255, Math.round(rgb[1] * 256)),
b = Math.min(255, Math.round(rgb[2] * 256));
return [r,g,b];
}
function rgb2hex(rgbArr) {
var r = (rgbArr[0]).toString(16); if (r.length < 2) r = '0' + r;
var g = (rgbArr[1]).toString(16); if (g.length < 2) g = '0' + g;
var b = (rgbArr[2]).toString(16); if (b.length < 2) b = '0' + b;
return ('#' + r + g + b)
}
function hsv2hex(h, s, v) { return rgb2hex(hsv2rgb(h, s, v)) }
/** count()
*
* Counts the occurences of unique items, and returns the result as an object / map.
*
* @param data : Data to be processed.
* @param fCompare : Compare function, as defined for array.sort(). If undefined, the default comparison is used.
* @param fName : Naming function for the arrays.
*/
function count(data, fCompare, fName) {
// Initialize.
if (typeof(fName) === 'undefined') fName = function(x) { return(x); }
if (typeof(fCompare) === 'undefined') fCompare = function(a, b) { return(a-b); }
var sorted = data.sort(fCompare);
var counts = new Array();
var bin = 0;
// Loop through the sorted array and pick up the changes.
for (var i = 0; i < sorted.length; ++i) {
if ( i == 0 || (fCompare(sorted[i - 1], sorted[i]) != 0) ) {
bin = counts.length;
counts.push([fName(sorted[i]), 1]);
}
else counts[bin][1] = counts[bin][1] + 1;
}
return counts;
}
/**
* Add flatten function to arrays.
*/
Array.prototype.flatten = function() {
return ([].concat.apply([], this));
}
function strToFloat(s) {
try { var result = parseFloat($().calculator('calculate', s)); }
catch (Invalidexpression) { var result = NaN; }
finally { return(result); }
}
function escapeRegExp(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
Chart.prototype.plot = function() {
var values = this.values;
{ // Create row and column labels, if needed.
var showRowLabels = this.rowLabels;
var showColLabels = this.colLabels;
if (showRowLabels === 'auto') {
var rowLabels = new Array();
for (var row = 1; row < values.length; ++row)
if ( (values[row][0] !== '') && isNaN(strToFloat(values[row][0])) )
showRowLabels = true;
if (showRowLabels === 'auto') showRowLabels = false;
}
if (showColLabels === 'auto') {
var colLabels = new Array();
for (var col = 1; col < this.values[0].length; ++col)
if ( (values[0][col] !== '') && isNaN(strToFloat(values[0][col])) )
showColLabels = true;
if (showColLabels === 'auto') showColLabels = false;
}
var startRow = (showColLabels === true ? 1 : 0);
var startCol = (showRowLabels === true ? 1 : 0);
if (showRowLabels) {
var rowLabels = new Array();
for (var row = startRow; row < values.length; ++row)
rowLabels.push(values[row][0]);
}
if (showColLabels) {
var colLabels = new Array();
for (var col = startCol; col < values[0].length; ++col)
colLabels.push(values[0][col]);
}
}
{ // Preprocess the data.
if (this.dataMode === 'counts') {
values = new Array();
for (var i = startRow; i < this.values.length; ++i) {
values.push(new Array());
for (var j = startCol; j < this.values[i].length; ++j) {
values[values.length - 1].push(this.values[i][j]);
}
}
values = count(values.flatten(), this.fCompare, this.fName);
showRowLabels = true;
showColLabels = false;
startRow = 0;
startCol = 1;
rowLabels = new Array();
for (var row = startRow; row < values.length; ++row)
rowLabels.push(values[row][0]);
} else values = this.values;
}
{ // Chart's type-wise settings -- bounding box, margins, styling etc.
if (this.chartStyle === 'pie') {
xMin = -5;
yMin = -7;
yMax = 5;
xMax = 5 + 10 * (values[0].length - startCol - 1);
this.grid = false;
this.keepaspectratio = true;
}
else if (this.chartStyle === 'scatter') {
var xMin = Number.MAX_VALUE,
xMax = Number.MIN_VALUE,
yMin = Number.MAX_VALUE,
yMax = Number.MIN_VALUE,
value;
for (var row = startRow; row < values.length; ++row) {
var value = strToFloat(values[row][startCol]);
if (!isNaN(value)) {
xMin = Math.min(xMin, value);
xMax = Math.max(xMax, value);
}
var value = strToFloat(values[row][startCol + 1]);
if (!isNaN(value)) {
yMin = Math.min(yMin, value);
yMax = Math.max(yMax, value);
}
}
if (this.includeOrigo) {
xMin = Math.min(xMin, 0);
xMax = Math.max(xMax, 0);
yMin = Math.min(yMin, 0);
yMax = Math.max(yMax, 0);
}
}
else if ((this.chartStyle === 'line') || (this.chartStyle === 'spline')) {
var xMin = Number.MAX_VALUE,
xMax = Number.MIN_VALUE,
yMin = Number.MAX_VALUE,
yMax = Number.MIN_VALUE,
value;
if ((this.repeatPattern === 'x') || (this.repeatPattern === 'y')) {
for (var row = startRow; row < values.length; ++row)
for (var col = startCol; col < values.length; ++col) {
var value = strToFloat(values[row][col]);
if (!isNaN(value)) {
if (this.repeatPattern === 'x') {
xMin = Math.min(xMin, value);
xMax = Math.max(xMax, value);
}
if (this.repeatPattern === 'y') {
yMin = Math.min(yMin, value);
yMax = Math.max(yMax, value);
}
}
}
if (this.repeatPattern === 'x') {
yMin = 0;
yMax = values.length - 1;
}
if (this.repeatPattern === 'y') {
xMin = 0;
xMax = values.length - 1;
}
}
else if (this.repeatPattern === 'xyy') {
for (var row = startRow; row < values.length; ++row)
for (var col = startCol; col < values[row].length; ++col) {
var value = strToFloat(values[row][col]);
if (!isNaN(value)) {
if (col == startCol) {
xMin = Math.min(xMin, value);
xMax = Math.max(xMax, value);
} else {
yMin = Math.min(yMin, value);
yMax = Math.max(yMax, value);
}
}
}
}
else if (this.repeatPattern === 'xyxy') {
for (var row = startRow; row < values.length; ++row)
for (var col = startCol; col < values.length; ++col) {
var value = strToFloat(values[row][col]);
if (!isNaN(value)) {
if ((col - startCol) % 2 == 1) {
xMin = Math.min(xMin, value);
xMax = Math.max(xMax, value);
} else {
yMin = Math.min(yMin, value);
yMax = Math.max(yMax, value);
}
}
}
}
if (this.includeOrigo) {
xMin = Math.min(xMin, 0);
xMax = Math.max(xMax, 0);
yMin = Math.min(yMin, 0);
yMax = Math.max(yMax, 0);
}
}
else { // Bar charts
// Gather the minimums and maximums of the data.
var yMin = Number.MAX_VALUE,
yMax = Number.MIN_VALUE,
value;
for (var row = startRow; row < values.length; ++row)
for (var col = startCol; col < values[row].length; ++col) {
var value = strToFloat(values[row][col]);
if (!isNaN(value)) {
yMin = Math.min(yMin, value);
yMax = Math.max(yMax, value);
}
}
// All columns are created equal.
var xMin = startCol;
var xMax = (values.length - startRow + 1) * (values[0].length - startCol) - 2;
}
if (this.chartStyle === 'bar') {
yMin = -1;
xMin = 0.5;
xMax -= 0.5;
this.grid = false;
}
// Margins make 5% of each border.
var xMargin = (xMax - xMin) * 0.08;
var yMargin = (yMax - yMin) * 0.08;
if (xMargin == 0) xMargin = 2;
if (yMargin == 0) yMargin = 2;
}
{ // Initialize the board.
var board = JXG.JSXGraph.initBoard(
'chartframe-' + this.boxnum,
{
boundingbox : [xMin - xMargin, yMax + yMargin, xMax + xMargin, yMin - yMargin] /* (upper left), (lower right)*/,
axis: this.grid,
showCopyright:false,
showNavigation:false,
zoom:false,
pan: false,
grid : false,
keepaspectratio: (this.chartStyle === 'pie') || this.keepaspectratio
}
);
$('.chart .frame svg').height($('.chart .frame').height() + 30);
board.options.label.strokeColor = 'black';
}
{ // Create the color palette.
var colors = this.colors;
var highlightColors = this.highlightColors;
if (
((typeof(colors) === 'string') && (colors === 'auto')) ||
((typeof(highlightColors) === 'string') && (highlightColors === 'auto'))
) {
if (colors === 'auto') colors = new Array();
if (highlightColors === 'auto') highlightColors = new Array();
// Determine amount of needed colors
var nrow = values.length - startRow;
var ncol = values[0].length - startCol;
var n;
if ((this.chartStyle === 'pie') || (this.chartStyle === 'bar') || (this.chartStyle === 'scatter')) {
n = nrow;
} else if ((this.chartStyle === 'line') || (this.chartStyle === 'spline')) {
if (( this.repeatPattern === 'y' ) || ( this.repeatPattern === 'x' )) n = ncol;
else if ( this.repeatPattern === 'xy' ) n = ncol / 2;
else if ( this.repeatPattern === 'xyy' ) n = ncol - 1;
}
// Create the colors.
for (var i = 0; i < n; ++i) {
if (this.colors === 'auto') colors.push(hsv2hex(i * 360 / n, 100, 85)); // Them bright colors seem fancy, don't they?
if (this.highlightColors === 'auto') highlightColors.push(hsv2hex(i * 360 / n, 80, 100)); // Them bright colors seem fancy, don't they?
}
}
}
{ // Plot.
if (this.showLegend)
this.place.find('.frame')
.append('<ul class=legend></ul>')
.find('.legend')
.mouseenter(
function() {
$(this).toggleClass('legendleft');
}
);
board.suspendUpdate();
if (this.chartStyle === 'scatter') {
if ((values.length > startRow) && (values[0].length > startCol + 1)) {
var categories = new Array();
for (var row = startRow; row < values.length; ++row) {
var x = strToFloat(values[row][startCol]),
y = strToFloat(values[row][startCol + 1]),
size = null,
category;
if (values[row].length > startCol + 2) {
var category = categories.indexOf(values[row][startCol + 2]);
if (category == -1) {
categories.push(values[row][startCol + 2]);
category = categories.length - 1;
if (this.showLegend) {
var legend = values[row][startCol + 2];
if (legend.trim() === '') legend = 'NA' /* Not Acquired */;
this.place.find('.legend')
.append('<li><span class=colorbox style="background-color: ' + colors[category] + '"> </span> <span class="legendCaption">' + legend + '</span></li>');
}
}
if (values[row].length > startCol + 3) size = strToFloat(values[row][startCol + 3])
} else category = 0;
if (isNaN(x)) x = null;
if (isNaN(y)) y = null;
if (isNaN(size)) size = null;
// pairwise.complete.obs
if ((x !== null) && (y !== null)) {
board.create('point', [x, y],
{
name : (showRowLabels && (rowLabels[row - startRow].trim() !== '') ? '<span class="plotlabel">' + escapeRegExp(rowLabels[row - startRow]) + '</span>' : ''),
size : (size !== null ? size : 3),
withLabel : showRowLabels,
visible : true,
fixed : true,
strokeColor: colors[category],
highlightStrokeColor: colors[category],
fillColor: colors[category],
highlightFillColor: colors[category]
}
);
}
}
}
}
else if ((this.chartStyle === 'line') || (this.chartStyle === 'spline')) {
var x = new Array();
var y = new Array();
var colCounter = -1;
for (var col = startCol; col < this.cols; ++col) {
// Flush columns if necessary.
if ( this.repeatPattern === 'x' )
x = new Array();
else if ( this.repeatPattern === 'xy' && ((col-startCol) % 2) ) {
x = new Array();
y = new Array();
}
else if ( ( this.repeatPattern === 'y' ) || ( this.repeatPattern === 'xyy' ) )
y = new Array();
for (var row = startRow; row < values.length; ++row) {
var value = strToFloat(values[row][col]);
if (isNaN(value)) value = null;
// Store data to the proper array.
if ( this.repeatPattern === 'x' ) {
x.push(value);
if (col == startCol) y.push(row - startRow + 1);
}
else if ( this.repeatPattern === 'y' ) {
if (col == startCol) x.push(row - startRow + 1);
y.push(value);
}
else if ( this.repeatPattern === 'xy' ) {
if ( (col - startCol) % 2 === 0 ) x.push(value);
else if ( (col - startCol) % 2 === 1 ) y.push(value);
}
else if ( this.repeatPattern === 'xyy' ) {
if ( (col - startCol) === 0 ) x.push(value);
else y.push(value);
}
}
// Pairwise complete obs.
var tempX = new Array();
var tempY = new Array();
var i = 0;
if (this.showLegend && showColLabels) {
var legend = colLabels[col - startCol];
if (legend.trim() === '') legend = 'NA';
// Store data to the proper array.
if (
( this.repeatPattern === 'x' ) ||
( this.repeatPattern === 'y' ) ||
( ( this.repeatPattern === 'xy' ) && ( (col - startCol) % 2 === 1 ) ) ||
( ( this.repeatPattern === 'xyy' ) && ( (col - startCol) !== 0 ) )
) {
++colCounter;
this.place.find('.legend')
.append('<li><span class=colorbox style="background-color: ' +colors[colCounter] + '"> </span> <span class="legendCaption">' + legend + '</span></li>');
}
}
while (i <= x.length) {
if ( (i < x.length) && ((x[i] != null) && (y[i] != null)) ) {
tempX.push(x[i]);
tempY.push(y[i]);
board.createElement(
'point',
[x[i],y[i]],
{
name : (showRowLabels && (rowLabels[i].trim() !== '') ? '<span class="plotlabel">' + escapeRegExp(rowLabels[i]) + '</span>' : ''),
size : 3,
withLabel : showRowLabels,
visible : true,
fixed : true,
strokeColor: colors[colCounter % colors.length],
highlightStrokeColor: highlightColors[colCounter % highlightColors.length],
fillColor: colors[colCounter % colors.length],
highlightFillColor: highlightColors[colCounter % highlightColors.length]
}
);
} else { // Plot and flush.
if (tempX.length > 0) {
board.createElement(
(this.chartStyle === 'line' ? 'curve' : this.chartStyle),
[tempX,tempY],
{
strokeWidth : 2,
strokeColor: colors[colCounter % colors.length],
highlightStrokeColor: highlightColors[colCounter % highlightColors.length],
//fillColor: colors[(col - startCol) % colors.length],
//highlightFillColor: colors[(col - startCol) % colors.length],
labels : (showRowLabels ? rowLabels : '')
}
);
var tempX = new Array();
var tempY = new Array();
}
}
++i;
}
}
}
else /* bar chart, radar chart and pie chart */ {
for (var col = startCol; col < values[0].length; ++col) {
var data = new Array();
var rowList = new Array();
for (var row = startRow; row < values.length; ++row) {
var value = strToFloat(values[row][col]);
if (isNaN(value)) value = null;
if (value != null) {
data.push(value);
rowList.push( (values.length - startRow + 1) * (col - startCol) + row - startRow );
}
}
if (col == startCol) {
for (var i = 0; i < rowLabels.length; ++i) {
if (this.showLegend) {
var legend = rowLabels[i];
if (legend.trim() === '') legend = 'NA';
this.place.find('.legend')
.append('<li><span class=colorbox style="background-color: ' +colors[i] + '"> </span> <span class="legendCaption">' + legend + '</span></li>');
}
}
}
if (data.length > 0) {
if (this.chartStyle === 'pie') {
board.create('chart', data,
{
chartStyle : this.chartStyle,
strokeWidth : 3,
strokeColor : 'white',
highlightStrokeColor : 'white',
colors: colors,
highlightOnSector : true,
highlightColorArray: highlightColors,
opacity: 1.0,
fillOpacity: 1.0,
center: [10 * (col - startCol), 0]
}
);
board.create('text', [(col - startCol) * 10, -5, escapeRegExp('<span class="a">' + colLabels[col - startCol] + '</span>')], {anchorX:'middle', anchorY: 'top'});
}
else if (this.chartStyle === 'bar') {
board.create('chart', [rowList, data],
{
chartStyle : this.chartStyle,
strokeWidth : 3,
strokeColor : 'white',
highlightStrokeColor : 'white',
colors: colors,
highlightOnSector : true,
highlightColorArray: highlightColors,
opacity: 1.0,
fillOpacity: 1.0
}
);
board.create('text', [(col - startCol) * (values.length - startRow + 1) + (values.length - startRow) * 0.5, -0.5, escapeRegExp('<span class="columnCaption">' + colLabels[col - startCol] + '</span>')], {anchorX:'middle', anchorY: 'top'});
}
}
}
}
if (this.showLegend) this.place.find('.legend').find('.legendCaption').mathquill();
if (this.showColumnCaption) this.place.find('.a').mathquill();
this.place.find('.plotlabel').mathquill();
board.unsuspendUpdate();
if (board.keepaspectratio) {
var ratio = (yMax - yMin) / (xMax - xMin);
var minVal = this.place.find('.legend').height() + 36;
var newH = Math.min(Math.max(this.place.find('div.frame').width() * ratio + 30 /* padding at the bottom */, minVal), this.maxHeight);
var newW = newH / ratio;
this.place.find('div.frame').width(newW);
this.place.find('div.frame').height(newH);
this.place.find('svg').width(newW);
this.place.find('svg').height(newH);
board.setBoundingBox([xMin - xMargin, yMax + yMargin, xMax + xMargin, yMin - yMargin] /* (upper left), (lower right)*/, true);
if (this.grid) board.create('grid', []);
JXG.JSXGraph.boards.jxgBoard1.update()
}
}
}
}
{ /** jQuery Plugin interface **/
var defaultParams = {
chartStyle : 'scatter' /* \in ['line', 'spline', 'bar', 'pie', 'scatter'], radar not yet supported. */,
grid : true /* boolean */,
dataMode : 'normal' /* \in ['normal', 'counts']*/,
mode : 'free' /* \in ['tiny', 'small', 'medium', 'large', 'full', anything other is interpreted as 'free'] */,
main: 'auto' /* 'auto' or String */,
sub: 'auto' /* 'auto' or String */,
xlab: 'auto' /* 'auto' or String */,
ylab: 'auto' /* 'auto' or String */,
repeatPattern: 'xyy' /* \in ['x', 'y', 'xy', 'xyy'] */,
isSquare : false /* boolean */,
width : '500px' /* in any CSS-applicaple units */,
showLegend : true /* boolean */,
showColumnCaption : true /* boolean */,
height : '300px' /* in any CSS-applicable units */,
rowLabels : 'auto' /* 'auto' or an Array */,
fName : function(x) { return(x.toString()); } /* Function that returns a string. */,
fCompare : function(a, b) { return(a-b); } /* Function that implements comparison in JS. */,
colLabels : 'auto' /* 'auto' or an Array */,
colors : 'auto' /* 'auto' or an Array */,
highlightColors : 'auto' /* 'auto' or an Array */,
keepaspectratio : false /* boolean */,
showPlot : true /* boolean */,
includeOrigo : true
}
var methods = {
'init' : function(params) {
// call handler.
params = $.extend( defaultParams, params );
if (params.mode == 'tiny') {
params.width = '200px';
params.height = '150px';
}
else if (params.mode == 'small') {
params.width = '400px';
params.height = '300px';
}
else if (params.mode == 'medium') {
params.width = '512px';
params.height = '384px';
}
else if (params.mode == 'large') {
params.width = '640px';
params.height = '480px';
}
else if (params.mode == 'full') {
params.width = '100%';
params.height = '500px';
}
if (params.isSquare) params.width = params.height;
return this.each( function() {
params.place = $(this);
var chart = new Chart(params);
params.place.data('chart', chart);
});
},
'plot' : function(params) {
// call handler.
params = $.extend( defaultParams, params );
return this.each( function() {
params.place = $(this);
var chart = params.place.data('chart');
chart.plot(params);
});
}
}
$.fn.chart = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
}
else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
}
else {
$.error( 'Method ' + method + ' does not exist on jQuery.exam' );
return false;
}
}
}
})(jQuery)
//}}}
/***
|Name|Chat|
|Version|4|
|Author|Rolf Lindén (rolind@utu.fi)|
|Type|plugin|
|Requires|MathQuill, modern jQuery and jQuery UI.|
|Description|Adds realtime communications and message gateway through NodeJS and Socket.io.|
!!!!!Revisions
<<<
20130906.1500 ''Version 4''
* Added HTTPS encryption.
20130823.0921 ''Version 3''
* Added addressing system to both frontend and backend.
* Added client list to the client.
* Fixed the message gateway for external plugins. The specification definition should now be complete.
20130614.1027 ''Version 2''
* Completely rebuilt to use NodeJS and Websockets.
* Most of the gateway and chat functionality that was available in previous version (1.1.1) was implemented (Gateway not tested / usable yet).
<<<
!!!!!Code
***/
//{{{
/** About this code:
*
This program is very loosely based on TrophyIM v.0.03
released in 2008 by Michael Garvin. TrophyIM was published
under the MIT licence.
This code is not subject to MIT licence.
Modified for E-Math project (see http://emath.eu)
by Rolf Lindén 2013.
Copyright 2013 Rolf Lindén (rolind@utu.fi). All rights reserved.
*/
(function ($) {
{ /** EventQueue **/
/** Function: ref
* Reference function. Allows pointer structures in JavaScript.
*/
var ref = function(obj) { return function() { return obj; }; }
/** Constructor: EventQueue
*
* Creates a new event queue for the given gateway.
*
* @param gateway: jQuery plugin object that can handle 'checkeventqueue' calls.
* @param fnName: jQuery plugin name for the gateway.
*/
function EventQueue(gateway, fnName) {
this.gateways = [
{
'obj': gateway,
'fnName' : fnName
}
];
this.attached = new Array();
this.queue = new Array();
debug('new EventQueue():', this, gateway, fnName);
$('html').bind('announce', this, this.handleAnnouncement);
};
/** Function: addGateway
* Adds a new gateway for the events.
*
* @param gateway: jQuery object defining the new gateway.
*/
EventQueue.prototype.addGateway = function(gateway, fnName) {
debug('EventQueue.addGateway():', gateway, fnName);
this.gateways.push(
{
'obj': gateway,
'fnName' : fnName
}
);
};
/** Function: detach
* Detaches the given ID from the queue.
*
* @param id: Identifier of the attachable object to be detached.
*/
EventQueue.prototype.detach = function(id) {
for (item in this.attached) {
if (this.attached[item].senderID == id)
Array.splice(this.attached, item, 1);
}
};
/** Function: handleAnnouncement
*
* Handles the announcement of a new shareable item.
*
* @param event: Announce event. Event should contain EventQueue
* object as its data.
* @param announced: Parameter object containing the object ID and it's type.
*/
EventQueue.prototype.handleAnnouncement = function(event, announced) {
debug('EventQueue.handleAnnouncement():', event, announced);
if (!$('#' + announced.senderID).hasClass('reflection')) {
var attachable = {
'id': announced.senderID,
'fnName': announced.fnName
};
attachable['events'] = $('#' + announced.senderID)[announced.fnName]('attachables');
refObj = event.data;
// Attach events only once per type.
var alreadyConnected = false;
for (var i = 0; i < refObj.attached.length; ++i)
if (refObj.attached[i].fnName == attachable.fnName) alreadyConnected = true;
refObj.attached.push(attachable);
if (!alreadyConnected)
for (item in attachable.events) {
$('html').bind(attachable.events[item].eventType, refObj, refObj.push);
}
for (item in refObj.gateways)
refObj.gateways[item].obj[refObj.gateways[item].fnName]('checkattachable');
}
};
/** Function: getAttachable
*
* If an ID is given, returns that exact attachable item. If
* searched item doesn't exist, returns null. If ID is
* undefined, function lists all attachable objects.
*
* @param id: ID of the attachable object.
*
* @return Depending on the given id, either attachable item,
* list of attachable items or null.
*/
EventQueue.prototype.getAttachable = function(id) {
// No ID was defined, return a list.
if (typeof(id) === 'undefined') return this.attached;
// Find the given item.
for (item in this.attached)
if (this.attached[item].id == id) return this.attached[item];
// No such item exists.
return null;
}
/** Function: push
*
* Adds an event and its parameters to the queue.
*
* @param event : Event object to be added to the queue.
* Event should contain EventQueue object as its data.
* @param params: Parameters for the events. Should contain at least senderID.
*/
EventQueue.prototype.push = function(event, params) {
debug('EventQueue.push():', event, params);
if (typeof(params.remoteCommand) === 'undefined' || (!params.remoteCommand)) {
refObj = event.data;
refObj.queue.push(
{
'type' : event.type,
'params' : params,
'timeStamp' : new Date()
}
);
for (item in refObj.gateways)
refObj.gateways[item].obj[refObj.gateways[item].fnName]('checkeventqueue');
}
};
/** Function: getItem
*
* Returns item at the given index.
*
* @param index: index of the requested item.
* @return Item at the given index.
*/
EventQueue.prototype.getItem = function(index) { return this.queue[index]; }
/** Function: getTotalEventCount
*
* Returns the length of the event queue.
*/
EventQueue.prototype.getTotalEventCount = function() { return this.queue.length; }
}
{ /** Debug **/
var showDebug = false;
function debug() {
if (showDebug) {
var out = '';
for (var i = 0; i < arguments.length; ++i) {
if ( typeof(arguments[i]) == 'string' ) out += arguments[i];
else {
try {
out += JSON.stringify(arguments[i]);
}
catch (TypeError) {
out += arguments[i];
}
}
}
console.log(out);
}
}
}
{ /** Chat **/
function Chat(params) {
// Checks if editor's CSS information is already written to document's head.
if ($('head style#mucchatstyle').length == 0) {
{ /** CSS & glyphs **/
var sCSS =
".sharedItem{ background-color: #ccf !important; }\
.chatframe {\
width:100%;\
height: 600px;\
border: none;\
}\
.chatInfoBox {\
padding-left: 12px;\
padding-top: 8px;\
clear: both;\
}\
.privacyBtn {\
margin: 2px 0 0 17px !important;\
width: 176px;\
}\
.chat {\
background-color:#fff;\
padding: 28px 12px 22px 12px;\
background-color:#fff;\
/*margin: 0px;\*/\
/*margin-right: 240px;*/\
padding: 8px 12px 22px 12px;\
/*border-style: dashed;\
border-width: 1px;\
border-color: #ccc;*/\
resize: vertical;\
}\
.chatChoice {\
color: blue;\
text-decoration: underline;\
cursor: pointer;\
}\
div.chatmessage.private b {\
color: red;\
}\
.chatIcon {\
width: 15px;\
height: 15px;\
display: inline-block;\
background-image: url(data:image/png;base64,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\
YII=);\
}\
.emo-angel { background-position: 0px 0px; }\
.emo-angry { background-position: -15px -1px; }\
.emo-aww { background-position: -30px -1px; }\
.emo-blushing { background-position: -45px -1px; }\
.emo-confused { background-position: -60px -1px; }\
.emo-cool { background-position: -75px -1px; }\
.emo-creepy { background-position: -90px -1px; }\
.emo-crying { background-position: -105px -1px; }\
.emo-cthulhu { background-position: 0px -17px; height: 17px; }\
.emo-cute { background-position: -15px -18px; }\
.emo-cute-winkling { background-position: -30px -18px; }\
.emo-frowning { background-position: -60px -18px; }\
.emo-gasping { background-position: -75px -18px; }\
.emo-greedy { background-position: -90px -18px; }\
.emo-grinning { background-position: -105px -18px; }\
.emo-happy { background-position: 0px -34px; }\
.emo-happy-smiling { background-position: -15px -34px; }\
.emo-heart { background-position: -30px -36px; width: 11px; height: 13px; }\
.emo-irritated { background-position: -43px -34px; }\
.emo-irritated-2 { background-position: -58px -34px; }\
.emo-kissing { background-position: -73px -34px; }\
.emo-laughing { background-position: -88px -34px; }\
.emo-lips-sealed { background-position: -103px -34px; }\
.emo-madness { background-position: 0px -49px; }\
.emo-malicious { background-position: -15px -49px; }\
.emo-naww { background-position: -30px -49px; }\
.emo-pouting { background-position: -45px -49px; }\
.emo-shy { background-position: -60px -49px; }\
.emo-sick { background-position: -75px -49px; }\
.emo-smiling { background-position: -90px -49px; }\
.emo-speechless { background-position: -105px -49px; }\
.emo-spiteful { background-position: 0px -64px; }\
.emo-surprised { background-position: -30px -64px; }\
.emo-surprised-2 { background-position: -45px -64px; }\
.emo-terrified { background-position: -60px -64px; }\
.thumbs-down { background-position: -75px -64px; width: 11px; height: 14px; }\
.thumbs-up { background-position: -87px -64px; width: 11px; height: 14px; }\
.emo-tired { background-position: -99px -64px; }\
.emo-tongue-out-laughing { background-position: 0px -79px; }\
.emo-tongue-out { background-position: -15px -79px; }\
.emo-unsure { background-position: -75px -79px; }\
.emo-unsure-2 { background-position: -90px -79px; }\
.emo-winking { background-position: -105px -79px; }\
.emo-winking { background-position: 0px -94px; }\
.emo-winking-tongue-out { background-position: -15px -94px; }\
.geoItemCaption {\
width: 12em;\
height: 25px;\
margin: 1px;\
text-align: right;\
padding-right: 4px;\
padding-top: 4px;\
display: inline-block;\
background-color: #f8f8f8;\
color: #444;\
border: solid 1px gray;\
vertical-align: top;\
border-radius: 2px;\
}\
.chatBtn {\
margin: 2px;\
display: inline-block;\
padding: 6px 10px 8px 10px;\
vertical-align: text-top;\
display: inline-block;\
*display: inline;\
outline: none;\
cursor: pointer;\
text-align: center;\
text-decoration: none;\
text-shadow: 0 1px 1px rgba(0,0,0,.3);\
-webkit-border-radius: 2px;\
border-radius: 2px;\
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);\
box-shadow: 0 1px 2px rgba(0,0,0,.2);\
-webkit-user-select: none;\
-moz-user-select: none;\
-khtml-user-select: none;\
-ms-user-select: none;\
// color: #303030;\
border: solid 1px #b7b7b7;\
background: #fff;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ededed));\
background: -moz-linear-gradient(top, #fff, #ededed);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed');\
}\
.chatBtn:hover {\
text-decoration: none;\
background: #ededed;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));\
background: -moz-linear-gradient(top, #fff, #dcdcdc);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dcdcdc');\
}\
.chatBtn:active {\
position: relative;\
top: 1px;\
color: #999;\
background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));\
background: -moz-linear-gradient(top, #ededed, #fff);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed', endColorstr='#ffffff');\
}\
/* green */\
.green {\
color: #e8f0de;\
border: solid 1px #538312;\
background: #64991e;\
background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e));\
background: -moz-linear-gradient(top, #7db72f, #4e7d0e);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7db72f', endColorstr='#4e7d0e');\
}\
.green:hover {\
background: #538018;\
background: -webkit-gradient(linear, left top, left bottom, from(#6b9d28), to(#436b0c));\
background: -moz-linear-gradient(top, #6b9d28, #436b0c);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6b9d28', endColorstr='#436b0c');\
}\
.green:active {\
color: #a9c08c;\
background: -webkit-gradient(linear, left top, left bottom, from(#4e7d0e), to(#7db72f));\
background: -moz-linear-gradient(top, #4e7d0e, #7db72f);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4e7d0e', endColorstr='#7db72f');\
}\
/* white */\
.white {\
color: #303030;\
border: solid 1px #b7b7b7;\
background: #fff;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ededed));\
background: -moz-linear-gradient(top, #fff, #ededed);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed');\
}\
.white:hover {\
background: #ededed;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));\
background: -moz-linear-gradient(top, #fff, #dcdcdc);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dcdcdc');\
}\
.white:active {\
color: #999;\
background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));\
background: -moz-linear-gradient(top, #ededed, #fff);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed', endColorstr='#ffffff');\
}\
/* red */\
.red {\
color: #faddde;\
border: solid 1px #980c10;\
background: #d81b21;\
background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));\
background: -moz-linear-gradient(top, #ed1c24, #aa1317);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed1c24', endColorstr='#aa1317');\
}\
.red:hover {\
background: #b61318;\
background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));\
background: -moz-linear-gradient(top, #c9151b, #a11115);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c9151b', endColorstr='#a11115');\
}\
.red:active {\
color: #de898c;\
background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));\
background: -moz-linear-gradient(top, #aa1317, #ed1c24);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aa1317', endColorstr='#ed1c24');\
}\
/* gray */\
.gray {\
color: #202020;\
border: solid 1px #a7a7a7;\
background: #eee;\
background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#dcdcdc));\
background: -moz-linear-gradient(top, #eee, #dcdcdc);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#eeeeee, endColorstr=#dcdcdc);\
}\
.gray:hover {\
background: #ededed;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));\
background: -moz-linear-gradient(top, #fff, #dcdcdc);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffff, endColorstr=#dcdcdc);\
}\
.gray:active {\
color: #999;\
background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));\
background: -moz-linear-gradient(top, #ededed, #fff);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ededed, endColorstr=#ffffff);\
}\
.container1 {\
width: 100%;\
height: 40px;\
}\
.inputContainer {\
width: 100%;\
}\
.geoProperty {\
width: 200px;\
min-height: 25px;\
margin: 1px;\
text-align: left;\
padding-right: 4px;\
padding-left: 4px;\
padding-top: 4px;\
display: inline-block;\
background-color: #fff;\
border: solid 1px gray;\
vertical-align: top;\
border-radius: 2px;\
}\
.alignRight {\
float:right;\
}\
.alignLeft {\
float:left;\
}\
.NEWcorner { border-radius: 15px 15px 0px 0px; }\
.SEcorner { border-radius: 2px 2px 15px 2px; }\
.SWcorner { border-radius: 2px 2px 2px 15px; }\
.NEcorner { border-radius: 2px 15px 2px 2px; }\
.NWcorner { border-radius: 15px 2px 2px 2px; }\
.geoProperty .mathquill-rendered-math {\
width: 100%;\
height: 100%;\
border: none;\
margin-right: 10px;\
}\
.geoProperty .mathquill-editable.hasCursor, .geoProperty .mathquill-editable .hasCursor {\
-webkit-box-shadow: none;\
box-shadow: none;\
}\
.geoProperty input {\
width: 100%;\
height: 100%;\
border: none;\
margin-left: 0px;\
margin-top: -2px;\
outline: none;\
vertical-align: middle;\
}\
.geoProperty input[type='password'] {\
margin-top: -1px;\
}\
.geoProperty input[type='checkbox'] {\
width: 100%;\
height: 100%;\
border: none;\
margin-top: 4px;\
min-height: 15px;\
text-align: left;\
display: block;\
}\
.disconnectButton {\
color: #faddde;\
border: solid 1px #980c10;\
background: #d81b21;\
background: -webkit-gradient(linear, left top, left bottom, from(#ed1c24), to(#aa1317));\
background: -moz-linear-gradient(top, #ed1c24, #aa1317);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ed1c24', endColorstr='#aa1317');\
}\
.disconnectButton:hover {\
background: #b61318;\
background: -webkit-gradient(linear, left top, left bottom, from(#c9151b), to(#a11115));\
background: -moz-linear-gradient(top, #c9151b, #a11115);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#c9151b', endColorstr='#a11115');\
}\
.disconnectButton:active {\
color: #de898c;\
background: -webkit-gradient(linear, left top, left bottom, from(#aa1317), to(#ed1c24));\
background: -moz-linear-gradient(top, #aa1317, #ed1c24);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#aa1317', endColorstr='#ed1c24');\
}\
.connectButton {\
color: #e8f0de;\
border: solid 1px #538312;\
background: #64991e;\
background: -webkit-gradient(linear, left top, left bottom, from(#7db72f), to(#4e7d0e));\
background: -moz-linear-gradient(top, #7db72f, #4e7d0e);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7db72f', endColorstr='#4e7d0e');\
}\
.connectButton:hover {\
background: #538018;\
background: -webkit-gradient(linear, left top, left bottom, from(#6b9d28), to(#436b0c));\
background: -moz-linear-gradient(top, #6b9d28, #436b0c);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6b9d28', endColorstr='#436b0c');\
}\
.connectButton:active {\
color: #a9c08c;\
background: -webkit-gradient(linear, left top, left bottom, from(#4e7d0e), to(#7db72f));\
background: -moz-linear-gradient(top, #4e7d0e, #7db72f);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4e7d0e', endColorstr='#7db72f');\
}\
div.chatlogin {\
margin-right:auto;\
width: 392px;\
background-color:#fff;\
}\
.client-list:empty {\
display: none;\
}\
.client-list {\
width: 150px;\
background-color:#fff;\
float: right;\
clear:right;\
margin-top: 0px;\
padding: 8px 12px 22px 12px;\
border-style: dashed;\
border-width: 1px;\
border-color: #ccc;\
resize: vertical;\
overflow-x: none;\
overflow-y: auto;\
list-style-type: none;\
}\
.attachableItems {\
width: 150px;\
background-color:#fff;\
float: right;\
clear:right;\
margin-top: 8px;\
padding: 28px 12px 22px 12px;\
border-style: dashed;\
border-width: 1px;\
border-color: #ccc;\
overflow-x: none;\
overflow-y: auto;\
list-style-type: none;\
}\
.attachableItems:empty {\
display:none;\
}\
.hidden { display: none; }\
.client-list li:nth-child(odd) {\
background-color:#f2f2f2;\
-webkit-transition: background-color 0.5s ease;\
-moz-transition: background-color 0.5s ease;\
-o-transition: background-color 0.5s ease;\
transition: background-color 0.5s ease;\
}\
.client-list li.selected {\
background-color:highlight !important;\
border-radius: 2px;\
color: highlightText !important;\
-webkit-transition: all 0.5s ease;\
-moz-transition: all 0.5s ease;\
-o-transition: all 0.5s ease;\
transition: all 0.5s ease;\
}\
.client-list li:nth-child(even) {\
background-color:#fafafa;\
-webkit-transition: background-color 0.5s ease;\
-moz-transition: background-color 0.5s ease;\
-o-transition: background-color 0.5s ease;\
transition: background-color 0.5s ease;\
}\
.attachableItem, .client-list li {\
margin: 2px;\
min-height: 26px;\
line-height: 26px;\
padding-left: 10px;\
text-overflow: ellipsis;\
-webkit-user-select: none;\
-moz-user-select: none;\
-khtml-user-select: none;\
-ms-user-select: none;\
}\
.client-list li[contenteditable] {\
background-color: #cec;\
}\
.attachableItem:nth-child(odd) { background-color:#f2f2f2; }\
.attachableItem:nth-child(even) { background-color:#fafafa; }\
div.chattab_av { /*Available*/\
border-radius: 15px 15px 0px 0px;\
color: #000000;\
}\
div.chattab_aw { /*Away*/\
border-radius: 15px 15px 0px 0px;\
color: #a00000;\
}\
div.chattab_off { /*Offline*/\
border-radius: 15px 15px 0px 0px;\
color: #808080;\
font-style: italic;\
}\
.client-list li.available { /*Available*/\
color: #000000;\
}\
.client-list li.away { /*Away*/\
color: #a00000;\
}\
.client-list li.offline { /*Offline*/\
color: #808080;\
font-style: italic;\
}\
div.chattabID {\
display: none;\
}\
div.chattabname {\
display: inline-block;\
line-height:16px;\
margin-bottom: 6px;\
}\
input.statusButton {\
width: 100%;\
margin: 0px;\
}\
input.sendButton {\
width: 100%;\
margin: 0px;\
display: none;\
}\
.chat:empty { display:none; }\
div.chattab {\
clear: none;\
float: left;\
cursor: pointer;\
padding: 6px 10px 0px 10px;\
vertical-align: text-top;\
display: inline-block;\
*display: inline;\
margin: 4px;\
outline: none;\
cursor: pointer;\
text-align: center;\
text-decoration: none;\
text-shadow: 0 1px 1px rgba(0,0,0,.3);\
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);\
box-shadow: 0 1px 2px rgba(0,0,0,.2);\
-webkit-border-radius: 15px 15px 0px 0px;\
border-radius: 2px;\
}\
div.chattab:first-child { margin-left: 0; }\
div.chattab:last-child { margin-right: 0; }\
div.chattab_f { /*Foreground*/\
color: #303030;\
border: solid 1px #b7b7b7;\
background: #fff;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#ededed));\
background: -moz-linear-gradient(top, #fff, #ededed);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#ededed');\
}\
div.chattab_f:hover {\
background: #ededed;\
background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#dcdcdc));\
background: -moz-linear-gradient(top, #fff, #dcdcdc);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dcdcdc');\
}\
div.chattab_f:active {\
color: #999;\
background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#fff));\
background: -moz-linear-gradient(top, #ededed, #fff);\
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed', endColorstr='#ffffff');\
}\
div.chattab_b { /* Background */\
color: #888;\
border: 1px white solid;\
}\
div.chattab_a { /* Alert (background/has new message) */\
border: 1px red solid;\
}\
.highlight{\
box-shadow: 0px 0px 60px #fff;\
-webkit-transition: all 0.5s ease;\
-moz-transition: all 0.5s ease;\
-o-transition: all 0.5s ease;\
transition: all 0.5s ease;\
}\
span.math {\
background-color: red;\
min-width: 10px;\
display: inline-block;\
}\
.inline {\
display: inline-block;\
}\
div.chatbox { /* Collection of chat messages */\
min-height: 100px;\
height: 600px;\
resize: vertical;\
width: calc(100% - 195px);\
background-color: #fff;\
float:left;\
overflow: auto;\
border: 1px #ccc solid;\
/*-webkit-box-shadow: inset 5px 5px 20px #eee;\
box-shadow: inset 5px 5px 20px #eee;*/\
}\
div.chatinput {\
min-height: 20px;\
background-color: rgb(200, 200, 255)!important;\
}\
div.chatmessage:nth-child(odd) { background-color:rgba(242, 242, 242, 128); }\
div.chatmessage:nth-child(even) { background-color:rgba(250, 250, 250, 128); }\
div.chatmessage { /*Each individual chat message*/\
white-space: pre-wrap;\
padding:4px;\
}\
.chat .history { color: gray; }\
div.chatmessage:nth-child(odd) { background-color:rgba(242, 242, 242, 128); }\
div.chatmessage:nth-child(even) { background-color:rgba(250, 250, 250, 128); }";
}
$('head').append('<style id="mucchatstyle" type="text/css">' + sCSS + '</style>');
}
// Variables that are related to parsing LaTeX strings.
this.startLatex = '$';//'[latex]';
this.endLatex = '$';//'[/latex]';
this.translations = {
'and': 'and',
'everyone': 'everyone'
}
this.latexRegExp = new RegExp(this.escapeRegExp(this.startLatex) + '(.*?)' + this.escapeRegExp(this.endLatex), 'ig');
this.UI = "\
<div class='chatbox'>\
<div class='inputContainer'>\
<div class='chatinput chatmessage' contenteditable=\"true\"></div>\
<input type='button' class='chatBtn sendButton' value='Send'/>\
</div>\
</div>\
<ul class='client-list" + (params.showClientList ? '' : ' hidden') + "'></ul>\
<ul class='attachableItems'></ul>\
<div><input type=\"button\" value=\"Private\" class=\"privacyBtn chatBtn\" /></div>";
// Parameters as chat variables.
this.params = params;
for (var item in params)
this[item] = params[item];
this.courseID = this.courseID.toUpperCase(); // Make course id case-insensitive.
this.username = this.username.toUpperCase(); // Make course id case-insensitive.
this.place.empty().append(this.UI).addClass('chat').find('.privacyBtn').click(function() { $(this).toggleClass('red') });
// Variables that are related to component sharing.
// These are internal and should not be overridden by params.
this.boxnum = $('.chat').length - 1;
this.sysMsgCount = 0;
this.currentEventIndex = 0;
this.reflectionCount = 0;
this.shared = new Array();
// Initialize the event queue.
if (typeof(document.eventQueue) == 'undefined')
document.eventQueue = new EventQueue(this.place, 'chat');
else
document.eventQueue.addGateway(this.place, 'chat');
// Socket.io connection.
debug('Initializing connection...');
if (typeof(io) == 'undefined') throw(new Error('Object "io" for Socket.IO is not defined. The device cannot load scripts from the server -- check the internet connection.'));
this.socket = io.connect(params.URL, { 'force new connection': true, secure: true}/*, {host: params.host, port: 50100}*/);
this.addSocketHandlers();
debug('Connection created and socket handlers declared.');
// Key bindings and click handlers.
this.place.find('input.sendButton').click( this.sendButtonClick );
this.addKeyBinds();
}
Chat.prototype.sendButtonClick = function() {
// Fetch the message from the input box.
var chatBox = this.place.find('.chatbox');
// Create a hidden temp div and copy user's input into it.
chatBox.find('.chatinput').after('<div class="tempdiv" style="display:none;"></div>');
chatBox.find('.tempdiv').html( chatBox.find('.chatinput').html() );
// Find the corresponding MathQuill Elements.
var elements = chatBox.find('.chatinput span.mathquill-rendered-math');
var tempElements = chatBox.find('.tempdiv span.mathquill-rendered-math');
// Replace MathQuill elements with their escaped versions.
for (var i = 0; i < elements.length; i++) {
if (elements.eq(i).hasClass('mathquill-rendered-math')) {
var latexStr = elements.eq(i).mathquill('latex') || "";
tempElements.eq(i).replaceWith(this.startLatex + latexStr + this.endLatex);
}
}
// Collect the message and remove the temp div.
var messageStr = chatBox.find('.tempdiv').html();
chatBox.find('.tempdiv').remove();
this.sendMessage(
this.getSelectedUsers(),
messageStr,
'chat',
!this.place.find('input.privacyBtn').hasClass('red')
);
// Clear the input box.
this.place.find('.chatinput').html('');
}
/** Function: closeShared
*
* Function closes shared objects defined by parameter id.
* Parameter id can be either undefined, string or an array
* of strings. This causes the function to close either
* all, one or given set of items among the shared items,
* respectively.
*/
Chat.prototype.closeShared = function(id) {
// Determine the shared items to be closed.
if (typeof(id) === 'undefined') var items = this.shared;
else {
// id needs to be an array of IDs.
if (Array.isArray(id)) var idArr = id;
else idArr = new Array(id);
// Make the data indexable.
var sharedIDs = new Array();
for (var i in this.shared) sharedIDs[i] = this.shared[i].id;
// Select shared objects matching the given IDs.
var items = new Array();
for (var i in idArr) {
var item = sharedIDs.indexOf(idArr[i]);
if (item >= 0) items.push(this.shared[item]);
/* else idArr[i] is not shared and should be handled. */
}
}
// Process the selected variables.
var attachableItems = this.place.find('.attachableItems');
for (var item in items) {
if (items[item].reflection) {
// Destroy the reflection assuming the shared object is inside a dialog.
var sharedObj = $('#' + items[item].id).dialog('destroy').remove();
} else {
attachableItems.find('li[relatedid="' + items[item].id + '"]').removeClass('sharedItem');
}
var index = sharedIDs.indexOf(items[item].id);
this.shared.splice(index, 1);
}
return items;
}
/** Function: escapeRegExp
*
* Returns the escaped version of the original string st.
* it can be used inside a regular expression.
*
* @param str The original string.
* @return The escaped string.
**/
Chat.prototype.escapeRegExp = function(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|\"\']/g, "\\$&");
}
/** Function fillAttachableItems
*
* Fills the list of attachable items in the chat client UI,
* and adds proper events (click, mouseenter, mouseleave)
* to it.
*/
Chat.prototype.fillAttachableItems = function() {
parent = this;
debug('Chat.fillAttachableItems()');
var attachableItems = this.place.find('.attachableItems').empty();
for (item in this.attachable) {
attachableItems
.append('<li id="attachable-' + this.boxnum + '-' + item + '" relatedid="' + this.attachable[item].id + '" class="attachableItem">' + this.attachable[item].id + ' (' + this.attachable[item].fnName + ')</li>');
attachableItems
.find('#attachable-' + this.boxnum + '-' + item)
.click(
{
'itemID': this.attachable[item].id,
'senderID' : 'attachable-' + this.boxnum + '-' + item
},
function(e) { parent.shareItem(e); }
)
.mouseenter(this.attachable[item].id, function (event) { $('#' + event.data).addClass('highlight'); })
.mouseleave(this.attachable[item].id, function (event) { $('#' + event.data).removeClass('highlight'); });
}
}
/** Function: htmlDecode
*
* Converts HTML encoded string back to ASCII form.
* Only rudimentary symbols are converted.
*/
Chat.prototype.htmlDecode = function(input) {
var entities= {
"&": "&",
"<": "<",
">": ">",
"'": "'",
""": '"'
};
for (var prop in entities) {
if (entities.hasOwnProperty(prop)) {
input = input.replace(new RegExp(prop, "g"), entities[prop]);
}
}
return input;
}
Chat.prototype.getUserName = function() {
return(this.username);
}
Chat.prototype.getNick = function(resource) {
if ( resource.search(/^[0-9]{32}$/) >= 0 ) // Seems legit
return( this.place.find('.client-list li[resourceid="' + resource + '"]').eq(0).text() );
else return resource; // The given parameter is not a valid resource id. Pass the parameter through.
}
Chat.prototype.getNicks = function(addressObj) {
var nameStr = '';
var itemCounter = 0;
for (var item in addressObj) {
if ( (item != this.courseID) || (Object.keys(addressObj).length > 1) ) {
nameStr += item
if (addressObj[item].length > 0) nameStr += ': ';
}
// Go through the users in the current room.
for (var i = 0; i < addressObj[item].length; ++i) {
nameStr += this.getNick(addressObj[item][i]);
if (i < addressObj[item].length - 2) nameStr += ', ';
else if (i == addressObj[item].length - 2) nameStr += ' ' + this.translations['and'] + ' ';
}
if (addressObj[item].length == 0) nameStr += this.translations['everyone'];
++itemCounter;
if ((Object.keys(addressObj).length > 1) && (itemCounter < Object.keys(addressObj).length)) nameStr += '; ';
}
return(nameStr);
}
Chat.prototype.sortList = function(list, clickf) {
var items = list.find('li').get();
items.sort(
function(a,b) {
var keyA = $(a).text().toLowerCase();
var keyB = $(b).text().toLowerCase();
if (keyA < keyB) return -1;
if (keyA > keyB) return 1;
return 0;
}
);
var ul = list.empty();
$.each(
items,
function(i, li) {
ul.append(li);
}
);
var items = ul.find('li');
for (var i = 0; i < items.length; ++i) {
items.eq(i).bind('click.chat', clickf);
}
}
Chat.prototype.selectUser = function(item) {
$(this).toggleClass('selected');
}
Chat.prototype.makeNameEditable = function() {
this.place.find('.client-list li[resourceid="' + this.resourceID + '"]').attr('contenteditable', true)
.focus(
this,
function(e) {
var parent = e.data;
var self = parent.place.find('.client-list li[resourceid="' + parent.resourceID + '"]');
self.attr('original', self.text());
self.text('');
}
)
.blur(
this,
function(e) {
var parent = e.data;
var self = parent.place.find('.client-list li[resourceid="' + parent.resourceID + '"]');
self.text(self.attr('original'));
}
)
.keydown(
this,
function(e) {
if (e.keyCode == 13) {
var parent = e.data;
var self = parent.place.find('.client-list li[resourceid="' + parent.resourceID + '"]');
var candidate = (self.text()).trim();
self.text(candidate);
var target = {}; target[parent.courseID] = new Array();
parent.sendMessage(target, '/nick ' + candidate, 'chat', false);
self.blur();
}
}
).unbind('click.chat');
}
Chat.prototype.setClientList = function(list) {
var clientList = this.place.find('.client-list');
for (var i = 0; i < list.length; ++i) {
clientList.append('<li username="' + list[i].username + '" resourceid="' + list[i].resourceID + '">' + list[i].nick + '</li>');
}
this.sortList(clientList, this.selectUser);
this.makeNameEditable();
}
Chat.prototype.onMessage = function(data) {
var from = data.from;
var to = data.to;
var type = data.type;
if (typeof(data.message) !== 'undefined') {
if (data.type == 'chat') this.addMessage(data);
else if (data.type == 'new-user') {
if ( (from[this.courseID].length == 1) && (from[this.courseID][0] == 'Server') ) {
debug('onMessage(): New user', data);
var clientList = this.place.find('.client-list');
// Add the new user, if the person doesn't exist.
if ( clientList.find('li[resourceid="' + data.message.resourceID + '"]').length == 0 ) {
clientList.append('<li username="' + data.message.username + '" resourceid="' + data.message.resourceID + '">' + data.message.nick + '</li>');
clientList.find('li[resourceid="' + data.message.resourceID + '"]').bind(
'click.chat',
function() {
$(this).toggleClass('selected');
}
);
this.sortList(clientList, this.selectUser);
this.makeNameEditable();
}
}
}
else if (data.type == 'remove-user') {
if ( (from[this.courseID].length == 1) && (from[this.courseID][0] == 'Server') ) {
debug('onMessage(): Remove user', data);
var clientList = this.place.find('.client-list');
clientList.find('li[resourceid="' + data.message.resourceID + '"]').remove();
}
}
else if (data.type == 'update-userinfo') {
if ( (from[this.courseID].length == 1) && (from[this.courseID][0] == 'Server') ) {
debug('onMessage(): Update user info', data);
var clientList = this.place.find('.client-list');
clientList.find('li[resourceid="' + data.message.resourceID + '"]').text(data.message.nick);
// TODO Handle status updates appropriately.
//jQuery('.client-list li[resourceid="' + data.message.resourceID + '"]').text(data.message.status);
this.sortList(clientList, this.selectUser);
this.makeNameEditable();
}
}
else if (data.type == 'client-list') {
debug('onMessage(): Client list', data);
if ( (from[this.courseID].length == 1) && (from[this.courseID][0] == 'Server') ) {
this.setClientList(data.message);
}
}
else if (data.type == 'share') { // Share request
var msgObj = data.message;
var parent = this;
this.addMessage(
{
'message': '<i>' + this.getNicks(from) + ' wants to share a ' + msgObj.fnName + ' with you.</i>',
'type' : 'shareRequest',
'id' : msgObj.id,
'choices' : [
{
'action' : function() {
$('body')
.append('<div id="reflection-' + parent.reflectionCount + '" class="reflection" remoteid="' + msgObj.id + '"/>')
.find('#reflection-' + parent.reflectionCount)[msgObj.fnName]()
.dialog(
{
width: 'auto',
title: 'Reflection from ' + parent.getNicks(from),
close: function(event, ui) {
parent.closeShared( $(this).attr('id') );
var response = {
'id' : msgObj.id,
'reflection' : false,
'responseid' : msgObj.msgid,
'response': false
}
parent.sendMessage(from, response, 'response');
}
}
);
// Allow message passing to begin.
parent.shared.push(
{
'id': 'reflection-' + parent.reflectionCount,
'reflection' : true,
'remoteid' : msgObj.id,
'fnName' : msgObj.fnName,
'sharedWith' : from,
'startTime' : new Date()
}
);
++parent.reflectionCount;
// Same code as in the sending part of the app.
// Dialog close quits sharing.
var response = {
'id' : msgObj.id,
'reflection' : false,
'responseid' : msgObj.msgid,
'response': true
}
parent.sendMessage(from, response, 'response');
},
'name' : "Accept"
},
{
'action' : function() {
var response = {
'id' : msgObj.id,
'reflection' : false,
'responseid' : msgObj.msgid,
'response': false
}
parent.sendMessage(from, response, 'response');
},
'name' : 'Decline'
}
],
'from' : this.getUserAddress()
}
);
}
else if (data.type == 'response') { // Sharing response.
debug('Chat.onMessage(), response:', this, data);
var msgObj = data.message;
var current = $('#' + msgObj.responseid);
if (msgObj.response === true) {
current.append(' Accepted.');//.append('<p />').append('-- insert cancel link here --');
// Allow message passing to begin.
this.shared.push(
{
'id': msgObj.id,
'responseid' : msgObj.responseid,
'reflection' : false,
'sharedWith' : from,
'startTime' : new Date()
}
);
this.handleEvents();
$('li[relatedid="' + msgObj.id + '"]').addClass('sharedItem');
// TODO Create a 'Cancel' button or a similar control to quit sharing.
} else {
if (msgObj.reflection === true) {
for (var item in this.shared)
if (this.shared[item].remoteid === msgObj.id) {
var objID = this.shared[item].id;
break;
}
} else var objID = msgObj.id;
var closed = this.closeShared(objID);
if (!closed.reflection) $('#' + msgObj.responseid).remove();
}
}
else if (data.type == 'event') { // Sharing event.
var msgObj = data.message;
msgObj.params.remoteCommand = true;
var i = 0;
var shareIndex = -1;
while ((i < this.shared.length) && (shareIndex < 0)) {
if (
(
msgObj.reflection &&
(this.shared[i].id == msgObj.params.senderID)
) ||
(
(!msgObj.reflection) &&
(this.shared[i].remoteid == msgObj.params.senderID)
)
) shareIndex = i;
++i;
}
if (shareIndex >= 0) {
var sharedElement = this.shared[shareIndex];
var targetObj = null;
if (sharedElement.reflection) targetObj = $('div.reflection[remoteid="' + msgObj.params.senderID + '"]');
else targetObj = $('#' + msgObj.params.senderID);
targetObj[msgObj.fnName](msgObj.action, msgObj.params);
}
}
else if (data.type == 'external') { // External system message.
var msgObj = data.message;
msgObj.from = from;
msgObj.to = to;
this.place.trigger('chat_external_message', [msgObj]);
}
}
}
Chat.prototype.getSelectedUsers = function() {
var selected = this.place.find('.client-list li.selected');
var target = new Object();
target[this.courseID] = new Array();
for (var i = 0; i < selected.length; ++i) target[this.courseID].push(selected.eq(i).attr('resourceid'));
return (target);
}
/** Function: shareItem
*
* Initiates sharing protocol aiming to share individual
* plugin components of a client.
*
* @param event: Event passed to the function by JavaScript.
*/
Chat.prototype.shareItem = function(event) {
debug('Chat.shareItem():', event, this);
var selectedUsers = this.getSelectedUsers();
var itemID = event.data.itemID;
var senderID = event.data.senderID;
var senderItem = this.place.find('#' + senderID);
if (senderItem.hasClass('sharedItem')) { // Re-click quits sharing.
var closed = this.closeShared(senderItem.attr('relatedid'));
// Send close message.
var response = {
'id' : itemID /* Item related to this message. */,
'responseid' : null /* No response expected */,
'reflection' : true,
'response': false /* Close connection */
}
senderItem.removeClass('sharedItem');
this.place.find('#' + closed[0].responseid).remove();
this.sendMessage(selectedUsers, response, 'response');
} else { // First click starts sharing.
var itemData = document.eventQueue.getAttachable(itemID);
itemData.msgid = 'systemMessage-' + this.sysMsgCount;
this.addMessage(
{
'message': '<i>Sent request to share ' + itemID + ' with ' + this.getNicks(selectedUsers) + '..</i>',
'type' : 'shareStatus',
'id' : itemID,
'choices' : [/* Should contain 'Cancel' option. */],
'from' : this.getUserAddress()
}
);
this.sendMessage(selectedUsers, itemData, 'share');
}
}
/** Function: replaceURLs
*
* Replaces the URLs from a string with a corresponding
* link.
*
* @param msg: The message to be processed.
* @return String with URLs replaced with corresponding
* links.
*/
Chat.prototype.replaceURLs = function(msg) {
var temp = msg.replace(/((?:http|ftp|https):\/\/[\w\-_]+(?:\.[\w\-_]+)+(?:[\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)/g, '<a href="$1" target="_blank">$1</a>'); // HTTP, HTTPS, FTP.
temp = temp.replace(/(spotify:track:[a-zA-Z0-9]{22})/g, '<a href="$1" class="spotifyLink">$1</a>'); // Spotify.
return(temp);
}
/** Function: replaceSmileys
*
* Replaces the smileys from a string with their icon /
* glyph / image counterparts.
*
* @param msg: The message to be processed.
* @return String with smileys replaced with corresponding tags.
*/
Chat.prototype.replaceSmileys = function(msg) {
/* rolind 18042013.1549:
*
* It would be nice to use "<3" for the heart, but it
* would mess with math notations such as "1<3", and
* adding smileys after mathquill() would cause
* unpleasant side effects.
*/
msg = msg
.replace(/:saint:|:angel:/g, '<span class="chatIcon emo-angel" />')
.replace(/>\(/g, '<span class="chatIcon emo-angry" />')
.replace(/\^\^/g, '<span class="chatIcon emo-aww" />')
.replace(/:\./g, '<span class="chatIcon emo-blushing" />')
.replace(/:s([^a-zA-Z0-9])|:s^|:\?/g, '<span class="chatIcon emo-confused" />$1')
.replace(/B\)|8-\)/g, '<span class="chatIcon emo-cool" />')
.replace(/:evilgrin:|:creepy:/g, '<span class="chatIcon emo-creepy" />')
.replace(/:cry:/g, '<span class="chatIcon emo-crying" />')
.replace(/=3([^a-zA-Z0-9])|=3^|:3([^a-zA-Z0-9])|:3^/g, '<span class="chatIcon emo-cute" />$1')
.replace(/;3/g, '<span class="chatIcon emo-cute-winkling" />')
.replace(/=\(|:\(|:sad:|:frown:/g, '<span class="chatIcon emo-frowning" />')
.replace(/:o([^a-zA-Z0-9])|:o^/ig, '<span class="chatIcon emo-gasping" />$1')
.replace(/\$\)/ig, '<span class="chatIcon emo-greedy" />')
.replace(/:grin:|:virn:/g, '<span class="chatIcon emo-grinning" />')
.replace(/\^\^/g, '<span class="chatIcon emo-happy-smiling" />')
.replace(/:heart:/g, '<span class="chatIcon emo-heart" />')
.replace(/x\./ig, '<span class="chatIcon emo-irritated" />')
.replace(/x\|/ig, '<span class="chatIcon emo-irritated-2" />')
.replace(/:\*/g, '<span class="chatIcon emo-kissing" />')
.replace(/:D([^a-zA-Z0-9])|:D^|:laugh:|:naur:/ig, '<span class="chatIcon emo-laughing" />$1')
.replace(/:x([^a-zA-Z0-9])|:x^/ig, '<span class="chatIcon emo-lips-sealed" />$1')
.replace(/>:D/g, '<span class="chatIcon emo-malicious" />')
.replace(/:C([^a-zA-Z0-9])|:C^/ig, '<span class="chatIcon emo-pouting" />$1')
.replace(/\^\.\^/g, '<span class="chatIcon emo-shy" />')
.replace(/x\\|x\//ig, '<span class="chatIcon emo-sick" />')
.replace(/:\)|=\)|:happy:/g, '<span class="chatIcon emo-smiling" />')
.replace(/\._\.|:\|/ig, '<span class="chatIcon emo-speechless" />')
.replace(/O_o/g, '<span class="chatIcon emo-surprised" />')
.replace(/o_O/g, '<span class="chatIcon emo-surprised-2" />')
.replace(/>:\)/g, '<span class="chatIcon emo-spiteful" />')
.replace(/=o/ig, '<span class="chatIcon emo-terrified" />')
.replace(/:y:|:yes:|:agree:|:kyllä:|:good:|:k:/g, '<span class="chatIcon thumbs-up" />')
.replace(/:n:|:no:|:disagree:|:bad:|:e:|:ei:/g, '<span class="chatIcon emo-thumbs-down" />')
.replace(/\|\)|-\.-/g, '<span class="chatIcon emo-tired" />')
.replace(/:p([^a-zA-Z0-9])|:p^/ig, '<span class="chatIcon emo-tongue-out" />$1')
.replace(/xp([^a-zA-Z0-9])/ig, '<span class="chatIcon emo-tongue-out-laughing" />$1')
.replace(/(?!:\/\/):\//g, '<span class="chatIcon emo-unsure" />') // Otherwise messes with URLs: "http://..".
.replace(/(?!:\\\\):\\/g, '<span class="chatIcon emo-unsure-2" />')
.replace(/;\)|:wink:/g, '<span class="chatIcon emo-winking" />')
.replace(/;D/g, '<span class="chatIcon emo-winking-grinning" />')
.replace(/;P/ig, '<span class="chatIcon emo-winking-tongue-out" />');
return(msg);
},
/** Function: handleAttachable
*
* Updates the 'attachable' array inside the chat plugin.
*/
Chat.prototype.handleAttachable = function() {
if (this.showAttachable) {
this.attachable = document.eventQueue.getAttachable();
this.fillAttachableItems();
}
}
/** Function: handleEvents
*
* Called uppon new events. The function decides if the
* events should be handled now or later, and passes the
* events through the chat gateway if needed.
*/
Chat.prototype.handleEvents = function() {
if (this.shared.length > 0) {
var eventCount = document.eventQueue.getTotalEventCount();
for (var i = this.currentEventIndex; i < eventCount; ++i) {
var currentItem = document.eventQueue.getItem(i);
var j = 0;
var shareIndex = -1;
while ((j < this.shared.length) && (shareIndex < 0)) {
if (this.shared[j].id == currentItem.params.senderID) shareIndex = j;
++j;
}
if (shareIndex >= 0) {
// Current event belongs to a shared object.
var sharedElement = this.shared[shareIndex];
if (currentItem.timeStamp > sharedElement.startTime) {
// Event has occured after the sharing started.
var targetID = null;
if (sharedElement.reflection) targetID = sharedElement.remoteid;
else targetID = currentItem.params.senderID;
var attachable = document.eventQueue.getAttachable(sharedElement.id);
var j = 0;
var action = null;
while ((j < attachable.events.length) && (action === null)) {
if (attachable.events[j].eventType == currentItem.type) action = attachable.events[j].action;
}
var msgData = currentItem;
delete msgData.type;
msgData.action = action;
msgData.params.senderID = targetID;
msgData.fnName = attachable.fnName;
msgData.reflection = sharedElement.reflection;
// TODO Here should be decided, who gets this message.
this.sendMessage(sharedElement.sharedWith, msgData, 'event');
}
}
}
this.currentEventIndex = eventCount;
}
}
Chat.prototype.strFill = function(s, fill, len) {
var temp = s;
for (var i = 0; i < len - temp.length; i += fill.length)
temp = fill + temp;
return(temp);
}
Chat.prototype.getUserAddress = function() {
var address = {};
address[this.courseID] = [ this.resourceID ];
return( address );
}
Chat.prototype.addMessage = function(data) {
if (data.type === 'chat') {
var msg = data.message;
msg = this.htmlDecode(msg)
.replace(/<\s*br[/\s]*>/ig, "\n") // Preserve <br> tags.
.replace(/(<([^>]+)>)/ig,"") // Remove all other html tags.
.replace(/\n\n/ig, "\n") // Remove excess newlines.
.replace(/\n/ig, "<br />"); // Restore <br> tags but none of their inner contents.
// Replace all Latex strings with MathQuill spans.
msg = msg.replace(this.latexRegExp, '<span class="math">$1</span>');
msg = this.replaceURLs(msg);
msg = this.replaceSmileys(msg);
var dateStr = this.strFill('' + data.timeStamp.getHours(), '0', 2) + '.' + this.strFill('' + data.timeStamp.getMinutes(), '0', 2);
var targetStr = ((typeof(data.to) !== 'undefined') && (data.to[this.courseID].length > 0) ? ' → ' + this.getNicks(data.to) : '');
var chatBox = this.place.find('.chatbox');
chatBox
.find('div.inputContainer')
.before(
'<div class="chatmessage' +
(typeof(data.history) !== 'undefined' ? ' history' : '') +
(data.public === false ? ' private' : '') + '">' +
//'from="' + this.escapeRegExp(JSON.stringify(data.from)) + '">' +
'<b>(' + dateStr + ') ' + data.nick + targetStr + ':</b> ' + msg + '</div>'
);
chatBox
.find('div.inputContainer')
.parents('.chatbox')
.find('div.chatmessage span.math')
.mathquill()
.removeClass('math');
// Scroll the chat box to the bottom.
chatBox.animate({ scrollTop: chatBox[0].scrollHeight}, 500);
}
else {
var msg = data;
var chatBox = this.place.find('.chatbox');
var msgID = this.sysMsgCount++;
chatBox
.find('div.inputContainer')
.before('<div id="systemMessage-' + msgID + '" type="' + msg.type + '" class="systemMessage chatmessage"></div')
var sysMsg = chatBox.find('#systemMessage-' + msgID).append(msg.message);
if (msg.choices.length > 0) {
var choiceArr = this.place.find('.choiceBar');
var choiceBar = $('<div id="shareChoiceBar-' + choiceArr.length + '" class="choiceBar"></div>');
for (item in msg.choices) {
choiceBar.append('<span id="shareChoice-' + choiceArr.length + '-' + item + '" class="chatChoice">' + msg.choices[item].name + '</span> ');
choiceBar.find('#shareChoice-' + choiceArr.length + '-' + item).click(
{
choiceBar: choiceBar,
msg : msg,
item : item
},
function(event) {
var choiceBar = event.data.choiceBar;
var msg = event.data.msg;
var item = event.data.item;
msg.choices[item].action();
choiceBar.parent().remove();
}
);
}
sysMsg.append('<p />').append(choiceBar);
}
}
}
Chat.prototype.sendMessage = function(to, data, type, public) {
var msgObj = {
from: this.getUserAddress(),
to: to,
type: type,
timeStamp: new Date() + '',
message: data,
public: ( (typeof(public) === 'undefined') || (public != true) ? false : true)
};
debug('Sent (message): ', msgObj);
this.socket.emit(
'message',
msgObj
);
}
Chat.prototype.addSocketHandlers = function () {
var parent = this;
$(window).unload( function() { parent.disconnect(); } );
this.socket.on(
'authorize',
function (data) {
parent.socket.emit(
'authorize-reply',
{
username: parent.username,
password: parent.password,
courseID: parent.courseID,
resourceID: parent.resourceID
}
);
debug('Sent credentials.');
}
);
this.socket.on(
'message',
function(data) {
debug('Received: ', data);
data.timeStamp = new Date(data.timeStamp);
parent.onMessage(data);
}
);
this.socket.on(
'authorization-failed',
function(data) {
debug('Authorization failed: ', data);
}
);
this.socket.on(
'authorization-success',
function(data) {
debug('Authorization success');
parent.socket.emit('join', parent.courseID);
}
);
this.socket.on(
'disconnect',
function(data) {
debug('Disconnected from the chat server.');
}
);
}
Chat.prototype.disconnect = function() {
this.socket.disconnect();
}
Chat.prototype.addKeyBinds = function() {
// Enter key press.
this.place.find('.chatinput').keydown(
this,
function(e) {
var parent = e.data;
if (e.keyCode == 13 && !e.shiftKey) {
// prevent default behavior
e.preventDefault();
parent.sendButtonClick();
}
});
// Math mode edits.
this.place.find('.chatinput').keyup(
this,
function(e) {
var parent = e.data;
var originalContent = parent.place.find('.chatinput').html();
var currentContent = originalContent;
var caretPos = currentContent.search(parent.latexRegExp);
if (caretPos == -1) caretPos = currentContent.search(new RegExp(parent.escapeRegExp(parent.startLatex)));
if (caretPos > -1) {
var elements = parent.place.find(".chatinput span.mathquill-rendered-math");
var latexStr = new Array(elements.length);
for (var i = 0; i < elements.length; i++) {
if (elements.eq(i).hasClass('mathquill-rendered-math')) {
latexStr[i] = elements.eq(i).mathquill('latex') || "";
elements.eq(i).replaceWith(parent.startLatex + latexStr[i] + parent.endLatex);
}
}
var currentContent = parent.place.find(".chatinput").html();
currentContent = currentContent
.replace(parent.latexRegExp, '<span class="math">$1</span>')
.replace(new RegExp(parent.escapeRegExp(parent.startLatex)), '<span class="math"></span>')
.trim() + " ";
if (currentContent !== originalContent) {
var elements = parent.place.find(".chatinput").html(currentContent).find('.math');
for (var i = 0; i < elements.length; i++) {
elements.eq(i).mathquill('editable');
}
elements.eq(elements.length - 1).click();
elements.removeClass('math');
var elements = parent.place.find(".chatinput span.mathquill-rendered-math");
for (var i = 0; i < elements.length; i++) {
if (elements.eq(i).hasClass('mathquill-rendered-math')) {
var latexStrStored = elements.eq(i).mathquill('latex') || "";
}
}
}
}
}
);
}
}
{ /** jQuery Plugin interface **/
var methods = {
'init' : function(params) {
debug('Chat init:', params);
var resourceID = '';
for(var i = 0; i < 32; ++i) resourceID += Math.random() * 10 | 0;
params = $.extend( {
'username' : null,
'password' : null,
'courseID' : null,
'port' : 80,
'hidden' : false,
'showAttachable' : false,
'showClientList' : false,
'resourceID' : resourceID
}, params);
return this.each( function() {
var chat = new Chat( $.extend({ 'place' : $(this) }, params) );
$(this).data('chat', chat);
$(this).data('params', params);
});
},
'send' : function(params) {
params = $.extend( {
'to' : getSelectedUsers(),
'message' : '=^.^=',
'type' : 'chat'
}, params);
return this.each( function() {
$(this).data('chat').sendMessage(params);
});
},
'checkeventqueue' : function(params) {
return this.each( function() {
$(this).data('chat').handleEvents();
});
},
'checkattachable' : function(params) {
return this.each( function() {
$(this).data('chat').handleAttachable();
});
},
'disconnect' : function(params) {
var parent = $(this);
return this.each( function() {
$(this).data('chat').disconnect();
});
}
}
$.fn.chat = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof(method) === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.chat' );
return false;
}
}
}
})(jQuery)
//}}}
//{{{
if (typeof config == 'undefined') {
var config = new Object();
config.macros = new Object();
}
config.macros.chat = {
/******************************
* Show chat
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
// Server connection settings. Change these to your server and port.
var serverHost = 'http://localhost';
var serverPort = '8080';
var chatdiv = '{{chat{\n}}}';
wikify(chatdiv, place, null, tiddler);
if (jQuery('head script[src='+serverhost + ':' + serverPort+'"/socket.io/socket.io.js"]').length == 0) {
var jPlace = jQuery(place);
jPlace.append('Connecting to the chat server...');
jQuery('head').append('<script type="text/javascript" src='+serverhost + ':' + serverPort+'"/socket.io/socket.io.js" charset="UTF-8"></script>');
var timerID = setInterval(
function() {
if (typeof(io) != 'undefined') {
clearInterval(timerID);
jPlace.empty().chat(
{
place : jPlace,
username : config.options.txtUserName,
password : config.options.txtUserKey,
courseID : Emathbook.options.pages[0].courseid,
URL : serverhost + ':' + serverPort,
showClientList : true,
showAttachable : false
}
);
jPlace.before('<span class="red chatBtn" id="closeChat">' + EbookDictionary.localize('close') + '</span>');
jQuery('#closeChat').click(function() {
jPlace.chat('disconnect');
Emathbook.closePageTwo();
});
jPlace.before('<h1>Chat</h1>');
jPlace.after('<div class="chatInfoBox">Change nick: <code>/nick Name</code><br /><code>$</code> enters the math mode.<br />Links are created automatically when identified.</div>');
var closeTimerID = setInterval(
function() {
if (jPlace.css('display') == 'none') {
clearInterval(closeTimerID);
jPlace.chat('disconnect');
}
},
2000
);
}
},
100
);
}
}
}
//}}}
!usage
{{{[img[chat.png]]}}}
[img[chat.png]]
!notes
Icon for chat app.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[chatlog.png]]}}}
[img[chatlog.png]]
!notes
Chatlog image
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAHwCAYAAAAcgVIhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANggAADYIB2aerLQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7J13WBRX24dvQAUL9l6wK9YgdkEFwdhFFHtJsGBssYXYokRjjRoTNVGsYEVjAQtWRBEUxaiIWBARQQSV3tsy3x/jjiwsxahR3m/u6+Ji98xpc3bmmeecmXl+Gjq1y/yYEZGyUJGpKIeMjIzMF4hWMa244tVLrtTQKqYV27JFy7K9e/fW+NydkpGRkVHH2bNnhfv+9+OLKTIV5Xr37s3q1as/d59kZGRk8kLD19e3nGb2lMjISM6dO8eBAwdUciYlJeHp6YmjoyNxcXF51hgUFMTRo0e5fPmylCYIAtevX2fDhg24uLiQkpKSb68yMjLYs2cPoaGhAKSlpeHg4CD9ubm5qS03duxYRowYIdavUICDA/j5vcuQmQmOjnD/fr7ts349PH8ufp4xI/+82UlKEtt88uRdWmKimBYYmH9ZOzuIiYHkZJg/X0zz8oJDhwrffmG4exd27RI/79olfn9P7OzsGDFiBP7+/h+tW0eOHOGHH35gw4YN/PHHHx+t3oJYv349h96OcY8ePYiKiipUuc2bN7Nnz55P1q8HDx4QFBSkdtvdu3d58eJFgXUMHz6cZ8+efeyufREI8+bNEwRBEGbMmCFMnDhRKFu2rJCdzZs3C2PGjBGqVasmPHz4UFBHZmam0KNHD2HAgAGClZWVlB4WFiYMGTJE2Llzp7B48WKhWbNmgkKhUFuHIAjCsmXLhGrVqgknTpwQBEEQIiMjhdq1awsbNmwQNmzYILi4uKgtV7du3XdfkpMFoWRJQejV613ayZOCUKaMIKxZk2fbUr7Xr8XPO3fmnzc7z58LQunSgjBq1Lu0XbvENnftyr+skZEgvHghCLGxgvDVV2Lao0eC4OVV+PYLw7NngnDpkvh56lRBOH36X1Uzfvx4wc3N7aN1Kz09XUhOThZSU1OF1NTUj1ZvQURERAhRUVGCIAhCq1athNfK370AXr16JURGRn6yfv3yyy/Cjh071G6bO3eucOTIkQLrCAwMFNLS0j521z4b8+bNEwBBxcPauHEjf/75Zy6LNm3aNPbu3UuNGjVU0mNiYvDw8ABAS0sLNzc3bGxsVPLUrFmTI0eOMH78eJYtW0b16tXx8vIC4PHjxzx69EjK6+/vz8OHD+nWrZtKHdWqVWPWrFnMmjWLgQMHFs4Mly8PGhqgvBo5OICV1bvtbm4wbhxMmgTnz79Lf/EC0tLEz0+fiv8jI+GHH8TyW7aI3pA6GjaE4GCIjxe/798PFhbvtru4wOjRMHUqXL2af//j4+HNG/FzZiYcPQoTJ4p9FQQxffNmOH0avvkG/vrrXb9PnABnZ5gyBZYsgehoMT0xEV69yt3W7t0wfLi4j9m9rhMn4NtvYdgwcbzeEycnJ+bOncvXX39Ny5YtOX36ND/99BOdO3fm+++/l/LNmzeP/v37079/fxwcHNTW9fz5c2bNmkWPHj2YO3cusbGxAFhZWbFy5UqMjY0ZNGiQWu8jPj6en3/+mW7dujF58mTJezly5AhXrlxRyZuamso333zDmTNnSE1NZcOGDXz99deMHDmSu2/HxsXFhYsXLwIwdOhQlfaVM4PsbNmyhUWLFmFubo6xsTFnz54FwMbGhnv37kn5Ro4cibe3NwcOHGDz5s0MGjSIp8pjEAgMDMTFxYU1a9YwaNAgIiIiWL9+Pebm5piamvLzzz9LeVeuXEl4eDjR0dEMGzZMSv/rr784duwYAPPnz8fMzAxzc3M2bdqkdty/NDQLzpI3QUFB/Prrr4XOHx0dTXBwMI0bNwbg9OnTnDx5EgCFQsGcOXNYv359rnKBgYF89dVXDB06lGvXrhW+g2PHwp49EBUlnrRNmrzbVrYsrF4N8+aJ/5VTuXPnRAMFosEByMqCkSNh61ZIT4eVK/Nuc9gwcSoXFAS6ulC16rttVarAb7+JU825c8V+5cWTJ3Dzpvh56VLw8BANypYt4j4BuLqKRmvxYtG4KY3AzZuwaBHY2ECrVtCnj5geEqLeUDZoIBq8UaNEA6VQiIZt1SpxbDZtglq18u5rHsTGxuLm5oazszN///03Q4YMoW3btly/fp1nz55JJ6udnR1ubm6cPXuW/fv3E680+NmwtbVl+PDhXLp0iYYNG+Lo6AhAcHAwmZmZeHp6YmZmhpOTU66y+/fvJyUlhStXrmBubo6dnR0gLoFkX+KIiYlh4MCBWFhY0KdPHw4fPkx0dDTnzp1j5cqVLFiwABCP45i3F63nz5+TkZGBp6cnPXv2VNt+ZGQkV65c4eTJkxw4cICVb48fc3Nztm3bBkBAQADBwcF06tSJUaNGMX36dJydnWnYsKFUT6NGjbCwsGDevHk4OztTvXp1Jk6cyMWLF3F3d+fJkyf4vV0GCQkJISMjg8zMTJ4rlzhy7POCBQtwc3Pj/PnzODs7E6k87r9gPshgtW3bllOnThUqb2pqKsOHD2fp0qVUr14dgDlz5mBrawvAhg0bsLKyyuXFlS9fntDQUHx9fZk+fTqTJ08ufActLeH4cTh4UDwZs1O3Lpw5A7/+CqmpkN9+VKkiGoS1a+Gff0RDkRejRomGztFRPPlztnn8uLhOlpkptl8YnJ1Fo6SvL65xvb1CAmBtDY0aiemXLr1LHzAA2rSBoUNFgxsRkXf9tWrB3r2i8UtOhuvXRWMbFSV6XwkJYtv/gt69e1OqVCmaNWtGuXLlJA/ZwMCAm28N8qVLlxg+fDgDBw7k5cuXXM1hVJOSknB3d+ePP/5gxIgRuLq6Sl4CwKi3v22HDh24detWrj64uLgwfPhwNDQ0sLS05PLlyygUilz5evXqxcyZMxk8eDAgeoj//PMPI0eOZMGCBdy4cUMyVNkZOXKk1L6Pj4/acbC0tKRkyZLo6ekREhIipbm5uZGSkoK9vf37Hdtv8fPzY9y4cfTt2xd/f/8813jVcfXqVUaMGMGAAQN48eKFytrzl0qx/6KR9PR0hgwZgoWFBWPHjlWb56+//qJx48YcPXoUX19fnj59StWqVenYsSO6uroAdO/eHYVCQVhYGLUKc8UvWRK++grWrRMX4DdvfrdtyhQYPFicMu3e/W7apI5z58RF6iVLoEwZ6Nw577xVqojT0SNHRCOTfcoxZgzMng3LlsGaNfm3mZ2kJNDRET/r6kL2Gx+lSon/ixUTjaDyRFSmKz8nJqqvW6EQjdqGDaKx/e470VCVKiUa54MHRaNoYSF6eO9JyZIlVT5raWkB4hKCQqEgKSmJZcuW4e3tjba2Nn379iVNObV9i46ODpUqVWLr1q3ovB0HTU3NXG0o68xJtWrVJO8hMTGRMmXKSP3Izrx581i5ciVdunShQoUK1KhRg8GDB2NmZqbSl7z2Ma/2c46DkuLFi2NlZcXevXs5ceIEy5cvl/YtKytLbT05t82ZM4eTJ09Kyyapqakq+UuVKkVSUpL0PTQ0lDp16pCWlsZPP/3EtWvXKFWqFFZWVrnG/UtExcNKSUkhLi4OQRCIjY2Vdj4jI4PY2FgUCgUJCQnSALx8+ZK9e/dK5ZXbsufPyMjAysqK9u3bM2bMGGJjY8nIyADAy8sLT09PQLz7cejQIZycnOjUqRO2tra0bduW0NBQYmJiyMzM5Pjx4+jo6BTOWClZuFCcyr01ehKPH4OZGRQvLq4t5cf9+2BoCM2awYEDoseSHytXwp9/ikZESVYWhIaCiYloJPLz0nLSr59oMDMyYMcO0XNUcuCA6CE6OUHHjqA8EU+cEKe2vr6iAWrUSH3dsbGioTMyEg2ou7uYHhUlTn9tbMSpoRrP5WOgpaVFQkICd+/eZfv27ZLXlTOPhYUFCxcuJCAggHv37r2XJ6Fc57p27Rrz5s1j0KBBavMNGTKEhQsX0qdPHyIjI/n2229ZtWoVXl5eBAcHS3cUPyY2Njb8+OOP9OvXTzJqhoaGnD59mkuXLpGY40JjaGiIs7Mz7u7upKamkpmZyZ07dzhy5Ija2U6ZMmUoV64cR48e5dChQ5w7dw4QxzQpKYm7d++ye/du6Tz80lHxsOzt7XF2dsbQ0JBBgwbxzTffYG1tzaVLl1i1ahUVK1bE1taWDh068OuvvxIbG4u3t7fkNX333XeEhYUBMGjQIDZv3kz58uWJj4/n8uXLksu5ePFizMzMePr0KQqFAmNjY8qWLSv1w8DAAD09PYoVK0ZQUBDz588nPT2drl275rkoq4KW1jsvqEED8Q/EKZnG2+djV64U17h0dMRF69KlxfSWLUUvCt7lHTcO5syBr78WjYWpae42dXSgXTvxc/Pm4h+IhqJ6ddDUFNeiBg8WjeeUKe/Whdq0AW1t0cAp66haFZSPgCxeLK4x9e8v9mHChHfttmwpGjR9fXHKqsTERJySliolTvcAKlWCt+uHNG4sfq9USayvVy+xn3PmQOXK4hR4+nSx31Wrin14T9q1a6dydZ81a1a27pmgq6uLjo4Oe/fu5e+//6Zhw4bs27ePunXr5qprzZo1XL9+nT179lC8eHGGDx8OiCe88tipWbOmygKzkgEDBlCvXj0OHTrEkCFD6Nmzp9SHcuXEFzymTJlC6dKl6devH7q6uri7uzN06FD279/PwYMHcXFxkW4GGRsbo62tDcCkSZOkOmrUqCH1Kzvdu3dX8bCyj0OdOnWoVauWynTQ3NwcQRDw8vKiWbNmlFEej4jTyNKlS3P16lUMDAzYt28f+/bto1y5cirnhkKhoHjx4gAcPHiQXbt2Ub58eXbv3k2lSpUoVqwYBw4c4PDhw+jp6bF3715pqeZLR3qsoShTrlw5Yfjw4UJycvLHqTAwUBB69vw4dX0q+vQRhNu3c6cvWiQIedwW/1CWLFki1K9f/6M+1vD/laioKMHe3l4YOnToR63X09NTaN269Uet83OjfKzhP1nD+i9Q3ub+KMTHi3cPly79eHV+CvT133mG2alTR/Xu5Edk6dKlLP3Sx6WIEBQURFxcnNpHiT6EBw8efJLp65fA/4zB+qiULSsumn/p/Pab+vR/cbdJ5r+nXbt2tFMuAXxEJk2a9NHr/FL4oMcaZGRkZP5LZIMlIyNTZJANloyMTJFBNlgyMjJFBtlgycjIFBlkgyUjI1NkkA2WjIxMkUE2WDIyMkUG2WDJyMgUGWSDJSMjU2SQDZaMjEyRQTZYMjIyRQbZYMnIyBQZchms5ORkKeZ0dpTB7JXRQvMiKiqKN0q1l7ekpaVx586dfHXfUlJSCA4Olv5y6h/Gx8dz8+ZNKUBgTrZv387WrVtJT0+X0tLT07l37x7BwcEqef39/fH19QXgzJkzUpzunHqM2UlNTeXOnTuF0oQDURwhP8EMb29vnmTXMMyHqKgoKVLk7du3JaUhZ2dnkpOT8yyXkZHB1q1b2b59e6Ha+VwcPHgQQRCIiorCVU0k1piYGI4ePUpISAjnsyscFUD2sXpfHj16xO3btwE4f/78FyvQ4OTkRFZWFtHR0YXWVyjKqBisb7/9lnbt2tGqVSuVTL///jvNmjWjRYsWKrJD2VEoFDRp0oR27doxdepUKf3Vq1e0bt2aDRs2MHToUMaNG6e2vLu7Oz169JDkvJQnKMC+ffuoX78+mzZt4tucwg5vsbOzQ19fX4rVfeHCBfT09Fi4cCF9+/ala9euhIeHA3DlyhXpwN+8ebNKujr+/vtvatWqxfLly+nWrRv9+vUrMP7W69evefjwYZ7bjx49yo0bN/KtQ0loaChbt24F4OnTp5LR9Pb2zjcOt6amJvr6+pJKzJeKctxDQ0PVyk2lpaURHBxMYmJinhcsdWQfq/fFy8tLMp5bt25VK9/1JXD16lWysrJ4+fLlfypC+7lQMVjbt2+XtNeyM23aNJ48eSLJcylRKBRSzGktLS38/f1zHXCVKlXi/v377Nmzh0uXLuHv7y/JO6WlpakEze/Tpw/Ozs44OztLoW5fv37NnDlzePz4MXv37uXChQtqd6REiRKYmJigpaVFXFwco0aNwsXFhVOnTuHv74+RkRGzZ8/OdzAGDBiQKy0sLIyJEyfi7e3N0aNHefLkCTVq1JCMgK+vL4GBgTg5OamojtSqVQtDQ0NAFD44ceIEv//+ey5FGBCll5RyZyAehGfOnFErRNCiRQsavA35bG5uLoXe9fDwYNOmTXh5eSG81S3U0tLCxMSEEiVK5Lvfn4qnT5/i7+/P6dOncXR0JCEhgdDQUHbt2sXLly+lfP3790dDGY46G6dOneLNmzdkZmZSsWJFbt++LSna5CQpKYlTp07x+++/S79D9rE6d+4cL1++xMHBQeUY9/b2lrynzMxMSTMwL3x8fNi8eTNubm55Ck4A3L9/nyNHjqjMSFxcXAgLC2Pnzp1qL/xxcXEqseqzsrJweas38PDhQ7Zu3YqLi4vKRapfv34qghxKTp8+zevXrwHxGN67d6+K4s+jR4+wt7fn+PHjKudgXu18KajsqTIGdE7ySvfx8ZHiY+eVr1ixYlK6QqEgOTlZ+r5mzRpWrVol5XV3d2fUqFEcOnRIkrS/cuUKrVu3Zt26dXz//ffSVC4/rly5IinuAGhoaGBtbc3x48fzVCMBmKFGmt7V1ZW2bdtKxlpLS4tx48Zx9OhRQJxGWlpa8urVK5ycnBg/fjwAt27dkrTzrK2tCQgIoGHDhjx48ECl/qCgICwsLKhWrRoKhQJTU1M8PT25d++eytgqOX78OJfeynktWbKEmJgYBEHg/Pnz1K5dm1OnTjF69OgCx+i/4MKFCwwbNox79+5x8+ZNhg8fzqJFi1AoFHTv3l2a9s+cOVPld8nMzGTChAncvXuXKlWqcPnyZUqUKEFqaipGRka5lhxAjO1+//59GjVqJI3xsWPHcH8rqjF//nymTp1KZmYm33//PadPnwZg06ZNBAQEAOKyxI8//pjvPp07d46aNWty48YNevfurTbP1KlTWbduHc+fP6dNmzbSUsj48eOZN28eIGoe5PTAS5cujY2NDQkJCQC4ublJyxTnz5+ncuXKBAcH07FjR+miNHv2bDIzM6U6FAoFNjY2+Pj4ULVqVdauXcv8+fPJzMxk4MCB0jT3woULVKpUidDQUDp27CiN/4ULF9S286XwQRFHDQwM1ApH5sX8+fPp1asXzZo1A0TPTTkgLVu2xMHBgeLFi7N+/Xru3bvHihUrePXqFZ6ensyYMYMKFSowaNAg7t69KwX+V0d4eHiuSI5NmzalRIkS+a6jFbYuQ0NDIiIipL6bmJgwc+ZMAPT19SVjqyQsLAw9PT3MzMwolU1+69atW2zZsgVHR0caNWrExYsX0dPTw/KtKs7Vq1dVlIHzQkNDgyVLlnDjxg309fX5+++/SUtLk4QSPidt2rRhwYIFpKSkUL58eYKDg6lRowZ+fn5cunRJ2lclSUlJDBkyhEGDBmFtbQ3AmDFjCAoK4saNG7Rs2ZKTJ09KFwYlYWFh9OvXDxMTExXRhuzMmjULExMTatSowdmzZ+nXr99778+CBQv4559/SEhI4MWLF7x+/Zqq2cJRp6amcuHCBWl9MiYmhhMnTmBtbU1mZiYrV65ET0+PpKQkzp07J50LIF7cLS0tOXLkCNbW1jg4OEj7+f3333P//n1SUlLQ1dXl5s2b0gVZSXJyMlZWVvTr14+JEyciCAL79+9n3759FCtWDIVCwf79+zE0NGT69On4+/uTkpJChQoVuH79OkZGRsyYMaPAdj4nH3SXUEdHR63CiTqWLVvGixcv+C1bWN9KlSpRuXJlAPT09OjQoQNt2rTh999/5+DBgwBUrlyZ9u3bY2FhQbdu3ejZs6fahdns1KlTJ9fU686dOygUCqm9wqKuLk9PT2rXri1NYxplk9CqXbt2rkX+AwcO4OPjQ4cOHVTWk9zd3WnQoIE0bfHx8SE0NBQHBwccHBxo2bJlodzy5ORk2rdvj7e3N7q6uigUCl6pk6T/DCg905IlS1KjRg1JKLdixYrSlCU7L168IDAwUEULcO7cuaxevRqFQkH58uXVTqf27t2Lr68vnTt3lhSac6L/Vgy2cuXKkpemoaEhXXiyeyrqyMrKomPHjri5uVG6dGlKliyZ67d++vQpNWvWVGlTOStQCqnm7EN2vv32W/bs2UNcXJzKDKZfv34cOnSIEiVKoKurS1BQUK6yYWFhBAQEYG5uDogX25cvX7Jv3z4cHBwIDAykyVv1cwsLCw4ePEjx4sVV6uvfv79KO3mtWX8uPshgJSYm4u/vX2C+VatW4efnx969e1Xm22FhYdKiaPa5vo+PD61btwZESaXg4GDJZX38+DEGBgb5tmdqakpmZiaHDx8GxKv25s2bGTt2rNq1kvwYOHAgAQEB0jQsNjYWe3t7lZsHHh4eUjshISHSiaFET0+PtWvX4ufnh6Ojo3Ri2Nra0qBBA8aNG4dCocDS0hJNTU1Wr14t/bVt27bAPl69epUOHTpga2tLp06d1N7lLSo0bdqUXbt2YWFhIZ1EJ0+e5I8//mDMmDF5GuJatWqxZs0a/Pz8OHz4cKHXX5o3by7dSSzoDqSfnx/Vq1dnwYIF9OnTR+1d3hYtWhARESFN6y5dupTn1FEdLVu2JCkpibVr1zJ06FA0NTVJSEjg+fPnLF++HCsrK7XGCsSLg6OjI4MGDSIwMJCaNWvSqFEjpk6dKh1PkyZNIikpiYCAAFasWMGwYcN49uwZIOqKPnv2TGpHmf4loTIlXLlyJYcOHSIxMREDAwMmT57MlClTOHnyJIsXLyYgIABLS0t69OjBn3/+yf3795k9ezbXr18HxEVrf39/oqOjMTAwwMHBgXLlyrFw4UJatGghTa1WrVpFnz592LlzJwqFgqVLl7J48WI8PT3R0NBAW1ublStXAqLHMnv2bFq0aEHNmjXp1KmTihutjpIlS0pu+PLly4mMjKRHjx5s2LDhvQeoUqVKODs7M3HiRMqUKUNoaChDhw5l4cKFUp6MjAxMTExITk5m8eLFuYxiu3bt0NfXJzExkZEjR1Ism8Dq0qVLWb16NSNHjmT//v2YmprSq1cvqlatKi1QF0TXrl2xs7PDwsKChISEAsfnS6djx47s2rWLwYMHc/jwYb755ht69eqFQqGQPLScdOnShfr165OSkoKFhUWhp8NWVlaMHTuWw4cPq3hG6mjdujWpqakMHDiQqKgoWrZsqTbfsmXLGDBgACVLlqR27dr06NGjUH1RMm7cOGbNmiUZUl1dXdq2bUvfvn2JioqiXr16eZZt164djo6OWFlZ4eTkxKpVq/j+++/R1tYmMTGRPn36MH36dLp06UKfPn2Ijo6mTp06Ujvt27eX0gs7e/qv+WJ0CWNjY4W4uDi121JTU4XU1NQ8y1apUkXYsmWLkJaWlqvOnGn/lujoaCEjI0Ml7ccffxQcHR2F1NRUIT09XW05hUIhhIeH57ldHa9evRIUCkW+edq0aaMyJrGxsSrb09PThS1btghVqlQpdLsyMl8iX6QuYX4L6QVdMfft20dWVlauW7z51fm+VKhQIc9t+fVPU1PzvVV1qxagKzhq1CjMzc1V2s25r5qamtSrV499+/a9V9syMl8qX5TB+hC+/vrrz9LumjVrPku7+T2Vr0RLS+u91k9kZL505HcJZWRkigyywZKRkSkyyAZLRkamyCAbLBkZmSKDbLBkZGSKDLLBkpGRKTLIBktGRqbIIBssGRmZIoNssGRkZIoMssGSkZEpMsgGS0ZGpsggGywZGZkig2ywZGRkigyywZL57MTHxxMREUFUVNR7x9z/UEJCQkhLS+Pp06cqQhjPnz8nLS2NwMDAfIVLPoTMzEwpOmxMTAzR0dGfpJ3C8OTJEzIyMnKFfC4sQUFBZGZmSoIenwoVg+Xm5saCBQuYMmWKSiY/Pz+WL1+OtbW1pOGXE0EQ2LVrFzNmzODPP/9U2bZs2TL69u3LxIkTOXPmjNryr1694vfff2fSpEm59AG9vLyYNGkSkydPzlNnrnHjxowYMUIUgMjIgG+/hWPH3mWIjwdrayggHjzW1qAM+9y+ff55sxMdLbaZXYYsLExMUyPtpcLAgRARIfbxbTxujh2D1asL335hcHMDZbzzBQvE7++JnZ0dbdq0wdPT86N16+rVq2zfvp1jx47h7Oz80eotDEuWLCEoKIgpU6ZIYY0BfvrpJ54/f87kyZPzFav9ECIiIiSFoz179rBt27ZP0k5OfHx8JPkwEA2n8twuSDUoL2bNmkVUVBRjx479WN1Ui4rBev78Oc2bN88Va+nFixfUqFGDq1ev5lJkViIIAmFhYZQtW1ZFnw/AyMgIe3t7vvvuO2bOnKnWikdHR6OhocGrV69UrHRYWBjjx49n5syZ9OrVC3Nzc7VXvIyMDJycnESdvsxMcHaGtWvfZTh8WDQm9+/nPyJ2dvBWFIK3Ml2FIjERzp5VbXPPHrh4EQID8y8bHQ0KBQgCKBWGTU1FY/cx6dABpk0TP8fHw7/QnVu6dCmGhoYqCtt5kZKSQlJSEjExMTx//hwQj5OcMcl79+6NlZUVQ4YMYcKECfnWmVPQNCoqiqysLIKDg/PsU1JSEikpKbx+/VpFmw9EkWCFQsHZs2dVAiBu2rSJjIwMLly4oKLCk5GRga+vb64Ld2JiYq66s5OSkoKfn1+hY82/evWKjIwMFa8rMTFR0hDMLmCRlpYmGdvY2FgyMjIICwsjKSlJbd0+Pj64u7sTERFBamoqxYoV49ChQ6Snp0s6CEri4+O5e/cu8fHxUlpycjJ3795V6dvu3buJiorC29u7UPv3b1EJ4Dd+/HjS09OZPn26SqY+ffoAokpydp4/f87x48eZNWsWmpqaLF68mFOnTuVyC5UKKHXq1KFx48Y8e/aMevXqce7cOQRBoHfv3jRr1oxmzZrlUuk4ceIEAwcOpGXLlrRs2RI7OztJkihfSpWCxo3h9m0wNIQDB2D48Hfb//pL9GIUCujcGVasAA0NWLcOpk8Hp3uHpgAAIABJREFUfX2YMUP0Qp49g8mTIT0dataEhQtBXTzvatWgeHF4/hzq1hWN5sCB77avXAmXLkFWluhJZYsLnwsvL9HQzZoFoaHw669w5w506wa2tlChAtjYQJUq4OEBtWrBsmXQpAn88Yfo3fn4iP1ZvBi6dhXLX74MS5aotjVzpmjINTVh2DCYNElMnz9fLJOaCuPGQQHGJCeOjo44OTmhq6vLq1ev+Prrr3n8+DElSpQgKCgIDw8PihcvzpQpU9DW1iY8PBxdXV12796dq65Lly7xxx9/UKFCBcLDw/nzzz9p1KgRvXr1on79+mhra+Pv78+OHTtyCXesX78eNzc3ypUrR0xMDJaWlsyZM4cHDx6waNEiatWqxYMHD5g9ezYDBgzAz88POzs7atasyYMHD5g7dy79+vXDw8ODefPmYWRkRGBgIPb29lSrVo25c+cSEhJCZmYmTZo0yRXUMS0tDUtLS5o2bcrjx4/p3bs3s2bNUjtmWVlZTJ8+nYoVK/Ldd98xcuRISbVp9erVNGvWjNGjR9O+fXvpwn/69Gm8vLxYv369pIyura3N06dPWb58uUoQR0EQOHbsGNHR0aSmpmJjY8ODBw84f/689Lvs2rWLevXqSePWvHlzIiIi2LdvH46OjuzZswdDQ0MCAgJwcXHB09OTjRs3UrlyZR4+fMiyZcvo2rXrex0rheWDIo6mp6cXet49YcIEfHx8MDc3p3v37oB4xRAKEGps1aqVNE2Ii4vj6dOnhISEFGywQPRQHBxAVxcqVoTsEl+jR8PUqeJnGxvw9hYNV1iYeIICKI1n9epw+rR48t+6BevXg5qTCoCxY0XPytxcNJQ6Ou+2TZsmGilBgCFDRIOUTSJMhfh4UF5FV6wAY2PYuFE0Njt3wg8/wIsXopG5ckX05BYuhCNHxHLXr8P586LH1qsXPHggeoHqVGeWLYNy5UTj3b07jBwplrtxA94KkZJNHfh90NHR4eTJk0RGRlK1alXu3btHy5Ytsba2xtPTE1NTU7Zt20ZWVhYvXrxg/PjxvHjxgtq1a6vUs2bNGvbs2UO1atU4e/Ysu3fvZsWKFQAMGTKEESNGcOjQIY4dO6ZWaahSpUocO3YMQRBo2rQpM2bMoHnz5hw/fpyEhATu37/PqlWrGDBgAK1ateLYsWMkJCTg6+vL+vXr6devH66urkyYMIGJEydK9d69e5eoqCj+/vtvQJTjioiIUAmJra2tzdmzZ0lLSyM0NJThw4erNVgpKSkMGzYMc3NzvvvuuzyXPwrCyMgIW1tbvLy8sLe3VzFYGhoajB8/Hn9/f2n8DA0NGTNmDG/evGH//v0cPXqUuXPncuzYMXbt2kXTpk2l8i4uLtjZ2dGtWzcpzdjYGGNjY2JjY/Hy8sLBweHLNFiNGzdm2bJlhcq7evVq6Srm4+NDx44dGTJkSIHljIyMaNiwIcbGxiQkJKCnp6ciRpovpqaiN6KjIxovP7932x49gi1b4PVr8U9PTzRY6tDQEL2Ue/egRAnIT3160CDRuISGih7JoUPvtt2+LRqb6Ghxu5tb3gYrO2fOwIYNYj/GjBHr/eGHd+1pakLPnqIXqJRP79MHSpaEOnWgRg14/Djv+i9eFPuZlATh4aJ317OnWL5XL9EzHTmy4H6qQSnCWblyZWrXri0pzdStW5eAgABMTU1ZtGgRDx8+pFq1akRGRuLj46NisOLi4rhx4waTJ08GRC8ku76k8uLVsGFDjhw5orYf7d+uR2poaNC8eXPu3r1L3bp1sba2pkyZMlSvXp1bt24B4trShAkT0NXVpVq1avj4+AAwefJkbG1t2bhxI6NHj+aHH37g5MmT+Pr6MmjQIED0pu7du6disBQKBSNGjACgRo0ahIaGqtUk3Lp1K2ZmZnz33XfvO8wqGBsbS+OhToosJ5cuXWL9+vVUrlyZlJQUSRdhxYoVknGeOXMmVlZWLFq0iPnz5xMfH8/kyZMZP348T548YdasWZQtW5by5ctz8+bND+p/fvxnMd2rVKlC9+7d6d+/P+7u7oVWk9XQ0OCvv/4iPT0dTU1NatasyVdffVW4RjU0xBN3zx5YtUrVYM2dK04T9fTgp5/yX8/Zt0+cYrq6itO9Dh3yzqujA23bih7btm3vDFZWltjmxYuitzd5cuHXkCpWhLg40YBERooenxLlXbWUFNGYammppoNoICtVeucxZichQfTgvL3F8r16id6Upqa4v48fi4ZduT/vSXZRkJwCIWLXojlz5owkod6hQ4dcXne5cuVo2LAh27dvp0qVKvm2kRdK+XqAgIAAmjVrxpYtW+jbty/Tpk3j9u3b0trt7t27GThwIJMnT8bHx0da16lfvz5HjhwhLi6OsWPH0rZtW4yMjHj69CkODg55tq2Umd+yZQsJCQmSR5mTGTNm8PjxY+zs7Fi6dCmVKlVSmcHcvn1bknCrWLEiMTExVKhQQRq7wo5HyZIlVdbS1q1bx7p162jevDm//fabtA5lYmLC1atXCQ0NxczMjF69etG2bVsuXLjAq1ev6N27N+bm5tjb22NtbY2VlRVnz57NJTz8MVExWPfu3SMgIICMjAycnZ3R19dHX1+f0NBQ/vnnH+Li4nBzcyMmJobOnTvz6NEj7O3tJb2/ixcv4u3tTVhYGM7OzpLbeOTIEVq3bs3jx4/Zt2+ftCh/4MABFAoFY8eOJTk5mfPnzxMUFIRCoeDUqVP079+f5ORkXF1dKVeuHPb29gwZMiRfXbZcLFoE33//7kRWIgiix3PnDhw9ClZWeddRvDgEBMA//4jTsoJOkPXrcxsjTU1xDezuXdGjO3cOWrQo3D4MGQI//ihOYZctE+9kKtm1S1wvO3QIsgtOuLqK09LAQHFKnJfidbFiotG6c0fs21svgydP4OFDca2uQYOCbxz8SypUqEBqaipr1qzh/v37KnfqsjNz5kxGjx5N//79SU1NRVtbm5kzZxa6HT8/P2xtbQkJCcHY2JgyZcpgYGDAwoULSU1N5cqVK5QoUQIAAwMDfv75ZxITE7ly5YqkI7ly5Uq0tbXR0dHh2bNntG7dmipVqrBu3TomT55Mhw4duH37NnPnzpXUvEEUR50+fTobNmzA3d2dihUrqu1jsWLFcHR0xMbGhnnz5rFmzRoaN27M7NmzSUlJUbnhYGFhwcSJE2nSpAkeHh506tSp0GNhZGTEggUL0NbWZvTo0RgYGPDLL7/QpEkT3N3dJe9w0qRJtG3blri4OCpXroyuri6zZs2iUaNGZGRkIAgCNWrUwMDAgD///JOgoKBcd/g/NhqIuoSsXr2a06dPS+4viBbWxMQEX19fjh8/LqU3atSIMWPG8OLFC86dOyfd2dm4caPKFWHChAlUqVKFTZs2ERgYSIsWLejVq5c0J75y5QqCIGBiYkJMTAx//PGHVLZEiRIsXLiQ9PR0Vq1axevXr+nYsWOe6s316tV7d/cxM1NceJ47VzWTp6fodRkZiSfknj2i12JiIhoYU1PxxO/eXVxAb9xYPFHT0mDvXvEEHj4crl0TF8OzExcHBw9CTnf+3DmxLgMD0cPbv180Hu3bi95Yx46i0Rk6VPRwdu8W6/DzE9eilCKcly+La1JDhogeHEDfvjBxorjW1K6duE1TU/QYK1cW+1SpkjiFLFlS3OcnT8Ryrq7i/jVuLO7PsWPiZz090UCVLy96Vq9eQZs2Yv/eypxNmDCB0aNHFygQ+vLlSzIyMiRBTm9vb+nECg4ORltbmxo1apCUlIS7uzv169dHR0eHcuXKqUz5lKSmpnLx4kWKFy9O165dKVWqFP/88w+tWrWiRIkSJCQkEBoaSvPmzVXKLVu2jCpVqtCyZUvKli2r4qEHBgby8OFDjI2Nefz4sdS/J0+e8OjRI7p27cqjR4/o1KkT4eHheHt7U6JECYyNjVXuKj579gwfHx+aNWtGq1atcvU9IiKCGzdu0K5dO169ekWrVq3Iysri4cOHGBgYEBYWhkKhQE9PD0EQ8PLyok2bNpQqVYrLly9TsWJFypYtS+nSpSUJuNu3b5OQkEDz5s2Jj4+nYcOG3L9/n7p166Krq0t6ejr+/v60adNG7VjeuXOHRo0aUblyZby9vUlOTqZNmzZERETQvHlzHjx4gJ+fHzVr1qRjx46UKFGCp0+fcvv2bSpWrEiXLl3Eu/KAv78/wcHBGBsbExAQIE3BPxbz58+XbmZ8MUKqH0L37t0FCwsLISkp6cMry8gQBAcHQRg27MPr+pT06SMIt2/nTl+0SBB27PgkTc6fP18wNTUVfHx8Pkn9n4KlS5cKf/311+fuhswH8EUKqX4IOZ/9+iDS00XvJMdjHF8cw4aJ3ltOunUT170+AatWrfok9X5KRo8eLU33ZIo2/zMG66NSqpS47vWlk9eDpZ9JVPZLpWHDhp+7CzIfCfldQhkZmSKDbLBkPhnPnj3DX/leZj789NNPnDx5Mld6SEgI9+7dk74rFAoaNmxIcHAwJiYmBdZ77do1Ro0axaFDh5g3b9579R0gMjKSdu3acefOHSwtLd+7vMzHR54Synwyrly5wvPnz2lRwOMb8fHx0jty2bl27Rq+vr60bt0aAC0tLW7fvo2urq5aA5eTDh06sH37dooXL87A7K9IFZJKlSpx6dIlSpcuzd69e9+7vMzHR/awZD4JGRkZbNy4EScnJwYNGsTNmzdJSEhg1apVmJubM27cOB5ne/r++vXrmJqa0r17d7y8vADxHcCjR48yaNAgPD09OXXqFIMHD6ZHjx4sWLCA2NhYUlNT6dGjB4q3T/gnJiZibm6OIAisXbsWCwsLevfuLT0rCLBhwwZ69eqFqakpy5cvB8SHRXv37k2PHj2YM2cOAAcPHsTS0hIzMzOWLFkiRgKR+ez8TzzWIPPlsXv3buHnn3+Wvm/YsEFYv369IAiCcOfOHWH48OGCIAjCjBkzhAEDBghpaWnCrVu3BEtLS0EQBOHgwYPC/PnzpfJxcXHS5/Xr1wu7du0SBEEQRo4cKZw9e1Zqc/bs2YIgCEJsbKwgCIKQlZUlDB48WAgICBBSU1OFZs2aSfWkpKQIgiAITZo0EdLT01XSlOUFQRAWLVokODs7f/CYyPw7/ucea5D58nFycqJ69erSu2bnz58nIyMDACsrK0qUKIGhoSF3795VW/7NmzfMmzeP4OBgUlJSqF27NtbW1nz77bc4OjrSq1cvHBwcpKgit2/fZufOnURHRxMaGsqlS5eYPHkynTp1onv37gwePJhvv/0WHR0dLCws6NatG4MGDWL8+PHo6OgQGhrKDz/8wIsXL4iLiyM+Ph4LC4v/ZrBk1CJPCWU+GZqamirvzFWvXp158+bh4OCAg4MDL1++pHjx4gDSE9MaGhpSmZzlly1bxrBhwzhz5gwTJ06U1r3Mzc3x8fHB19eX5ORkWrZsSVZWFnPnzmXjxo24urrSpUsXKf+uXbvYt28fycnJDB06FIBff/0VZ2dnypQpQ69evQDx6eoZM2Zw5swZhg8fXuhYVjKfDtlgyXwyDA0NuXTpEhcvXiQqKgpra2vs7Ozw8fHh6dOnHMseETaP8leuXOHChQu8efOGYsWKcefOHS5fvoy9vb2UT1NTUwoxo4wHpampSXp6Onfv3sXJyYlz584B4p2/gwcPkp6eTqNGjaQXgXfv3k1CQgKNGjWSAvYVK1aMW7ducf78eXnR/QtBC/jZ2NgYc2VoXhmZj0TVqlWpV68eN27coF69ehgZGdGpUydOnjyJl5cXLVq0oHHjxoAYqih7JIZOnTpRsWJFGjduzI0bN6hduzb9+/fn1q1bPH78mFmzZlGzZk3pDmTjxo3JyMhg0qRJ6LyNQda1a1ecnZ3JzMxk2rRp1KtXj1q1anHu3DlcXV0pWbIktra26Orq4u7uzsmTJ8nMzGTBggVUqFCBLl264OHhQUhICLNmzaJ27do0adLkvx9IGS5evIiXl5fqy88yMjIyXyLKl5/lKaGMjEyRQTZYMjIyRQbZYMnIyBQZchms5ORkSdwxO5mZmTx//lx6biYvoqKicsWrTkhI4ObNmwUG1X/y5Ak+Pj4qbSQnJxMcHKzyp+728vbt29m6dauK1FN6ejr37t3LJSvm7++P79u47GfOnJHkmXLKm2VHGfCssMIAwcHBXLt2Lc/t3t7ehYq3DeKYKu9y3b59m0ePHgHg7Oycr2ZeRkYGW7duZfv27YVq53Mxc+bMAsVIcuLs7MyxY8fYvn17niF51cVNz0lCQkKeWnyRSsm1txw6dAhXV1c2b96sEugyL5YuXUpQUBDTp0/PM5JqfuzYsQMPDw9WrVrFw4cP37v8/yIqBuvbb7+lXbt2uSIm/v777zRr1owWLVrkkuFSolAoaNKkCe3atWOqUo3mLSNHjsTe3p4pU6bQrVs36TWK7Bw7doy5c+dib29P+/btcXJyAsDX15dZs2ZJfw0bNlRrNOzs7NDX10frbSjkCxcuoKenx8KFC+nbty9du3aVtOSuXLnC+fPnAVG6LHu6Ov7++29q1arF8uXL6datG/369SM2NlZtXiWvX7/O9yA7evQoN27cyLcOJaGhoWzduhWAp0+fSvvv7e2d77NBmpqa6OvrY2dnV6h2PhfqImIWRPPmzWnRogXt27fPM2R2YaJepqWl5Snu26VLF5WLZ+vWrWnatCmdO3fOpeqjDjMzMypWrMjAgQPR1tYuMH9O2rdvT/369TExMZGijP5/R8Vgbd++Xe1TxtOmTePJkyfSLWglCoWCxMREQHwx1d/fn02bNuUqf+rUKXbu3MnJkyepWLEibm8Vh9PS0qSH+QYPHsyJEyfYsWMHe/fu5bfffgOgc+fOODs74+zsjK2tLZ07d1Yb36hEiRKYmJigpaVFXFwco0aNwsXFhVOnTuHv74+RkRGzZ8/OdzAGDBiQKy0sLIyJEyfi7e3N0aNHefLkCTVq1JCMgK+vL4GBgTg5OakEEaxVqxaGhoaA+H7biRMn+P3339V6A5GRkSov8169epUzZ86oFSpo0aKFFC/c3NxceuDSw8ODTZs24eXlJXkrWlpamJiYfLbgdR4eHhw5cgRbW1usra0JCAjA1dWVcePGqTyDpbwIKhQK/vjjD4YOHYq1tbXk6W/bto0RI0YwduxY6SLg6urKokWLOHr0qFov89ixY0RFRfHdd99JQQdjY2PZuHEj06dPlzxsJQcPHmTs2LFSKPCTJ0/y+vVrpk2bJilDnThxgh9//JFTp05JbR49elTFk3Z1dcXNzY3o6GhcXFyYOHEiT548kc6ThIQE1qxZw+DBg5k8eTJxcXFkZGSwYcMGrKysGD9+PC9fviQrK0vS/Lx8+fInU58uaqgYLOVTxznJK93Hx4eePXsWmA/EadixY8eIiIiQPLg1a9aoRLCMjo7G29sbe3t7+vbtm6uOnTt3FqgMDKKnVLVqVUmZR0NDA2tra44fP67WCCiZMWNGrjRXV1fatm0rGWstLS3GjRvH0aNHAXEaaWlpyatXr3BycmL8+PEA3Lp1C8e3ytHKk7Vhw4Yq6i0AQUFBWFhYUK1aNRQKBaampnh6enLv3j2VsVVy/PhxLl26BIgy6zExMQiCwPnz56lduzanTp2S5M8/Nw8ePGDevHkMHjwYMzMz+vTpw/Xr11m8eDErV66URBUOHDggCXwGBASwc+dO5s+fj46ODh4eHri5ubFlyxaWLVsmPdTZunVrtm3bRp8+fRg3blyutnv27En58uX5+eefsbGxAUSPR19fnylTpmBjYyNNGZ88eUJ4eDhLlizhl19+4eXLl5iamlKxYkWWLFkizRjatWvHjh076N69u/SAaqVKlVi/fr3U7tKlS6lbt64k7WVvb48gCNJL1tu2bSMzM5M9e/YwdepUtLS0OHToECEhIezatQtbW1tKlCiBIAh0796dHTt20Lp1a0ni7P87H7TobmBgIE3dCmLv3r1s2rSJpk2bSgfdtGnTVIzEo0eP+Ouvv/Dy8qJDDimthIQEzpw5w7BhwwpsKzw8nHbt2qmkNW3alBIlShCVXf6qEKiry9DQkIiICMmTMTExYebMmWzdupVr167leqs/LCwMPT09zMzMVA68W7duMXbsWBwdHenQoQPu7u7o6elhaWmJhYUFJUuWVIkHlRcaGhosWbKEypUro6+vz82bN7+Y10j69u1L586dGTlyJJGRkcyfP5/GjRtjZmaWK6x1tWrVuH79OocPH6ZatWpUrVqVypUr4+fnx4EDByhdujR16tQBRNm47du3s337dsLCwggKClKpS1dXFy0tLapXr06lSpW4efMmWlpaBAUFcfXqVWrVqiVddCpUqMDs2bNp3LgxvXv35sqVK5QpU4ZixYpRrVo1SRCjYsWKbNmyBUdHRwIDA4mIiKB79+74+/sTHR3NgwcP0NbWplGjRlSpUoXIyEh+/fVXfHx8cHV1BURdwrNnz+Li4kLjxo0lTcSrV69y5MgRatasSeXKldHS0qJUqVJs3LiRv//+m3/++Uf2svhAg6WjoyMpohTE6tWrcXd3V4ktVKlSJRV1lC5durBnzx5cXV2xsbFRWes6dOgQ/fv3p3Tp0gW2VadOnVxTrzt37qBQKNSqsbxvXZ6entSuXVtS72mUTQy1du3auRb5Dxw4gI+PDx06dFBZT3J3d6dBgwbSFM/Hx4fQ0FDpXbuWLVsWyvAkJyfTvn17vL290dXVRaFQ8EqdwvNnQDneWlpaVKhQQfr9SpYsmesE7NatG8eOHSM8PBwjIyOuX79O8+bNcXNzIzk5ma+//ppTp06RmJjI2LFj6datG2vXrkVPT6/AC1F0dDRlypShXr161KtXDxsbG0n1p3LlytJvWapUKbWGITo6mokTJ2JmZsa6deuoWrUq0dHRaGhoMGLECJycnHBwcMD6rQTbhQsX2L59O2PGjOGXX36RbuyMGjUKe3t7/P39MTQ05NmzZ5ibm3P48GFCQ0Pp3Lkz//zzj/R0fb9+/fjtt9/Q1tb+Vwv3/2t8kMFKTEwsMKKkQqFQMTwxMTGS7llYWJi0gJz9xExISKBixYrSAjoUfjoIYGpqSmZmpiSAmZSUxObNm/OUCMuPgQMHEhAQIE3DYmNjsbe3V5mGeHh4SO2EhISgr6+vUoeenh5r167Fz88PR0dHMjMzAbC1taVBgwaMGzcOhUKBpaUlmpqarF69WvpTJ7uek6tXr9KhQwdsbW3p1KmT2ru8RYHg4GBq1qzJ4sWLGTp0KP7+/oSGhlK+fHlsbW2xsbHB19eXFy9eUK5cOTp27EhQUFCed+zq168vxdzq2bMn4eHh1KtXj969e9OlSxfKly+fb3+yT+GDgoKoWrUq7du35/79+/hlE+UdN24cjo6OODs7Sy9T379/HwMDA1q0aCHpb4IoK6avr8/KlSvp0qULT5484dmzZ9SpUwc7OzsGDhzIgwcPePToEQ0aNKBt27Z4eHioaBL+f0bFYK1cuZL27duTmJiIgYEBW7ZsAcQFSAMDAx4/foylpSXTpk0DxB9FKWUN4qL1999/z4ULFzAwMODu3btERkby1Vdf0bt3b9q3b0+xYsWkEB07d+6UbrmvWLECY2NjTE1NmTBhgsra1oMHD4iPjy+0WGTJkiU5ceIEq1atonXr1jRu3Ji0tDTWrl373gNUqVIlnJ2dmTJlCm3btqVJkybUrFmThQsXSnkyMjIwMTHB1NSUxYsX5zKK7dq1Y9SoUVhYWDBy5EhJmBPENY+WLVsycuRIGjZsiKmpKb169WLs2LGYmJjk8tbU0bVrV/z8/LCwsGDMmDGSOvDnpmbNmip38LL/fvXq1aNmzZqAKGevoaHBzZs3MTc3p0+fPrx584bRo0fz8OFD+vTpQ+/evblz5w6TJ09GX1+f7t27Y2Zmxvbt25k7dy66urq52l+6dCm//PILkydPRktLiwMHDvDXX3/x9ddfM2bMGCIjIylevLjK3cS6detSo0YNABYvXsz69eulu+etW7fGzMyMw4cPM2vWLMlbbNCgAV999RWjRo2SljvGjBnD48ePMTc3p1SpUtK7uufOncPExIS+fftSpUoVevbsybVr16Q1vqSkJIYNG4aZmRkVKlSgR48eXLt2DRsbG1n55y2fPIBfRkaG8PLlS0GhUOSbLzY2VoiJiflXbVSpUkXYsmWLkJaWlqvOnGn/lujoaCEjI0Ml7ccffxQcHR2F1NRUKQBcThQKhRAeHp7ndnW8evWqwPFq06aNkJqaKn3PHnBOEAQhPT1d2LJli1ClSpVCtysj8yXynwbwK1asmHTVyo/sSrrvy759+8jKykIzh4z8h9SZkwpvlY/Vkd9zNpqamtI0uLAU9NzNqFGjMDc3V2k3575qampSr1499u3b915ty8h8qfzPRBz9+jNp8Snls/9r8nsqX4mWlha9e/f+D3ojI/PfIL9LKCMjU2SQDZaMjEyRQTZYMjIyRQbZYMnIyBQZZIMlIyNTZJANloyMTJFBNlgyMjJFBtlgycjIFBlkgyUjI1NkkA2WjIxMkUE2WDIyMkUG2WDJyMgUGWSDJSMjU2T4nzFYAQEBPHr0KF+RiUIRFgbK6Kd5SJp9dEJCIDMTsrJAGbAvPh5y6OJ9MElJoAyd/OqV+P09CQkJ4dGjR58lvvjz589JS0sjMDDwX/3OERERxMfHExoamivu/vuQmppKWFhYofK+fPmSxMREqe8F8fTpUxQKBQEBAf+qb8p9CwoKkiLb/i+hYrDWr19P586dc+kSuri4YG5uTv369fPUJczKymLcuHG0atUqly5hv379aNWqFW3btmXRokVqy7u7u9O0aVMMDAwwMDBg27Zt0rZVq1bRrVs32rRpI+kJ5qRLly44OTmJOnJpaVCvHryVZwJEo1C/PrzV98uTefNAebBYWuafNzsvX4ptbt78Lu3OHTHt77/zLztqlGhAEhJg0CDy8px0AAAgAElEQVQx7dy5gvv6vly7Bsqoq8uWQR46jPlx8eJFRo0ahbe398ftWw5iY2NZt26dStqSJUt49uwZU6ZMkWSz3gd7e3s8PT1Zvny5FDo5O1lZWSxZsqTAeu7du5frGFeS8/jeuHEjPj4+LF68uFDRY6dOnUpsbKwUG/59WblyJY8ePWL27Nlq49z7+/tjbGwsRU89ffr0v2rncyJFHL1165bw/PlzoWzZsirR/h49eiQEBgYKX331lfDw4UO1EQGzsrIEDw8P4eDBg4KVlZXKtoSEBEEQBCEzM1MwMjISvL29c5U/ffq0MHXq1Fzpd+/eFYyMjIT09HQhNDRUqFq1qpCYmJgrX926dd99SU4WhCpVBMHQUBAyM8W0X34RBAMDQViz5l2+p08FITRUtaKYGEFQRhV9/Vo13c9PEPKKAvr8uSA0aCAIHTu+S/v+e7HNXbvE71lZghAQIAjh4apljYwE4cULQYiNFYSvvhLTUlIE4e24SeTsa3S0IKSnC0JQkCBkj6qakCCOQUSE2G8laWmCEBcnfp46VRBOnxY/Z2YKwoMHYn05efZMEPz9342jIAjjx48X3Nzc1I9DNpKTk4XExEQhPj5eePnyZa7tkZGRQlJSktqy9+/fFzp06CCEh4cL8fHxgiAIQkxMjODn55crEmt6errg6+ur0kZmZqbg5+cnhISESGlJSUnCvXv3VKK0ZufNmzdC/fr1hfDwcJXIt4mJiUJUVJT0/caNG8LAgQOFtLQ04dmzZ1J6bGysULt2bZXyiYmJwr1791SizUZFRQmZ2cYzISFBSE5OFgRBEF6/fi08ePAgV99SUlKEO3fuCG/evJHS0tLShLt37wrh2Y6nuLg4wc/PT6X+7ISGhkpj8vTpU6F+/fq5ouh+iaiNONq2bVsVqXclTZs2BcgVq9zPz4+1a9eyZ88eNDQ06Nq1K6dOncpVXhnnOjY2lrS0NCkW9rZt21AoFEyZMgUQp3Xbtm2jf//+UrxvDw8PjI2NKV68OLVr16Z69ep4eXkVHLCvWDEwMxM9lb594eRJeBtLHoBVq+DZM0hJgdevwcUFdHTA2hrs7MDAANq3F6do/v7w009QqxY8eACzZ4Ma0VXKlIFmzcDHRyx//TqYmLzbvmABxMVBbCwkJ4OzM+QlinHsmNjuihXg6QmLFkGNGvDmDWzZAk2awOjR4lSyalV48kTsd9++sHq1WKZ8eXFaOWwYfP89XLwIp0/Dn3+qtmVjA6VKQXi4WGbHDhAE6NEDmjYV+/jVV/Ddd/mPeQ4cHR05dOgQ2traZGVl0b59e1asWAHA+PHjefPmDfHx8fTr1y+XXPyRI0cICQnh559/xsTEhFatWvHTTz9Rq1YtHjx4wJw5c+jfvz+enp7Y2tpiZGREYGAgW7duJSYmhrFjx9K9e3dCQ0Oxs7Ojfv36DBky5P/YO/O4nNL3j79TKRrDhJSxNLKNJZGyZGmxFCFCfMe+ZhshsmSGMZaYsYwZZsguIhJlV7KmRZaIEKWSLUq7lvv3x5mOHk/F9ztjZszveXt5vTr3cy/nnOc817nu7frQoEEDYmJisLe3V9Kh3LdvHykpKSxYsABTU1PGjh3LrFmzePDgAQUFBRgaGsoCv3FxcfTs2ZMqVaqQl5eHn58fvr6+pKamsmDBAoyNjXFycmLYsGEYGRlx69YtnJycGDNmDAsWLMDc3JwhQ4YA4ODgwPLly3n58iUbNmxAV1eX27dv4+Hhgbm5OXv37mXdunWyAMbRo0cJCgrC3d0dCwsLYmJi2Lp1K6mpqUybNo06deoQHR2Ns7OzLIpRRHHF6rp165Kenk5mZuafGpn3Q6MQ0z03N1fJwyrCxMREwcN68uSJ8PX1Vcjj7++v5GEJIYS9vb2oWLGimDlzppwWEREhwsPDhRBCREZGCg8PD7Fy5UrRsmVL4enpKYSQvLtmzZqJ5ORkceHCBVGuXDmxY8cOpfqVPCwDAyFu3BBiwAAhzp0TYtIkIZYsUfSwhBAiKUmIKVOEOHRIOnZwEOLKlaJKFfO+eiXEhQtC9OqlfHPi44UwNhbi9GnJe/H1FWLBAiGmTXvjYRWRkCDEV18JERIiHZfkYXl5CTF3rvS3o6MQYWHS3zt3ClH0fdnZvbme+/eFsLSU/p43TwgnJ+nvggIhGjSQPKTDh6VzE0LRwyrKFx8vhJWVdE8ePJDOqwRv5H09rPXr1wsbG5vfqy8QDRs2FIWFhSIsLEw4OjrK6Y0aNVLytBITE4WFhYVSna9evRIXLlwQvXv3FkIIMWfOHPHbb78p5Fm9erVYtGhRieeUnZ0t7ty5I1q3bq30WV5enqhfv758fOPGDTF48GD5uE+fPiIhIUGEhoaK6tWry15Mp06dRMLv3m/dt58ZIXma0dHRol27dkIIIS5fviy6du0qhBAiPj5emJiYKOR/8eKF8PHxEZMmTRJCCPHVV1+Jo0ePKuSZPn262Lp1a4nXmJ6eLiIiIuQ2SsPd3V1MmTKlzDz/FP6UmO56enr0fc9xHn9/f3Jycujbty/79u2jf//+ChJWLVu2pGXLloA05jV48GBGjx5No0aNcHd3Z9y4cejo6GBiYvLOeOcyTZtKY0urVsHcuVB8/GvbNmlsSV9fGt+qUqVkrwmk8aVRoyQPSl8fIiJKb7NzZ5gxQ/Le1q2Dn35689maNRAYKNURFyd5Yu+jBHTuHPwuWUaHDtL1FFGk+PLFF9IkQdFAa1F6uXJQvz4Uk6VSYvZsadxOXx9SUqTr691b8taKPM158yRv67/EwsLi99MoR4UKFXj16hWnTp2iXbt2crqJiQkXL16UlWVK4smTJ4waNUoWHo34/TsYN24cM2fOZO3atQwZMoQZM2YwePBgXF1dadKkCQMGDMDNzY3y5cszaNAg1NTUMDAw4MGDB7x48QJdXd1S2wwICCA6OhqH38cVMzIyuHbtGtWrV6dNmzayDJ2RkRF3795V8F5Akq5zcnJCU1OTmjVrEh0dTW5uLq1ateLp06ckJSWxfft2hg8fDkjjS7NmzaJy5cro6OjIIrqzZs3Czc0Nd3d3xowZg7OzMxMnTmTmzJmsXLmSoUOHMn36dF69esWQIUOoWLEiNWvW5PLly6Ve29q1a7ly5QoHDhwo8/v7p/GXzhJqa2vTpEmTd4p8vn79WkH23snJiUOHDuHp6cnDhw+VlJjLZMQIePkS3tb3W74c9uyRuj9ffCF1gUpj2zbo2VPKP2zYG6NQEmpq4OQEOjrSgHsRhYVSV+zAAdiwQerGldVmcZo3fzMREBUFxa//d908nj6V6iySECtKB8mQlWZsnj+Xuoq+vpKB1dB4c15z50r19OwpGaz/gbdFQQDMzMwUdP1u3bolv6yK0NbWVphV27p1K/b29uzZs4dhw4bJM2CGhob4+Phw4cIFQkJCCAoKQk9Pj+3btxMREUFiYiL79+/n6NGj6Ovr4+Pjw6JFi3j16pWs3F3aubZv356mTZvi5+eHn58fp06domfPnqVe19vpBw4coHHjxvj4+DB37lzS09PlNocOHcqOHTvYvXu33DVct24dEydOZNeuXfTo0UOeCTU2Nubo0aMcPXqUrVu3cvv2bYyMjPD19eXMmTMEBQVx7tw5vLy86Ny5M3v37mXChAnk5OSUeI6//vorhw8fZv/+/Qq/s48BBQ9r3759nD17lpycHFxcXLC1tcXW1pbw8HC8vLxISkpi6dKltG/fnvHjxxMWFsbMmTM58/ts0+LFiwkLCyM6OhoXFxemTp2KtrY2M2bMwNjYmJiYGC5dukRYWBggzWgUFBQwf/58fvjhB16+fElhYSGHDx9mzpw5ALx69Yq5c+dSuXJlvLy8WLZsWZlvRSXGjJH+v82XX0rjUgCXL4OdXel1mJhIP9jsbGlm7V36cG+NxwCSp2NgAAsXSsbl/n3F8a2yGDcORo+WPMD9+yVPrYg9eySDfPKk4nVGRkoznrGx0LUrVKhQct1Vq0rLGzw8JGNYtNQhLAy8vaFZM6nu99SEfB8sLS1ZsGABM2bM4MmTJ5iamlK1atW3TqsqGhoauLq6Ym1tjYmJCfPnzycrK4szZ87IP7SlS5dSvnx5KlSoQGxsLC1atOCXX37h1atX6OrqEhkZyaxZs9DS0mLatGmsXr2awMBApfZAMjb169dn6tSpdOjQgf79+7N8+XLGjh1L27ZtuXr1qtK419u0aNGCyZMnY2FhgYmJCQsWLKBGjRoEBgYqqC4NGTKEpk2b0rlzZ1kd28TEhDVr1hAVFUVwcLCcd9asWdSqVQshBFlZWRgaGrJo0SJ0dHTQ0tLi4cOHNGvWDA0NDSZNmoS6urqssv4258+f5+uvv2bkyJG4ubkB4Obm9l6qVv8E1JDGsFi2bBl3795VWF9SJOv95MkTbt26Jafr6upibGzMq1eviI2Nld+OoaGhCutbWrVqRaVKlYiIiODevXs0bdoUY2Nj+fP4+HiEEBgaGvL48WNCQ0PR1NTEysqKCr//wAoLCzl37hxPnz7F1NRUlnV/m9q1a3Py5EkaNmwouY2hofB7t0Pm4UPJA6pdW/KSzpyRfshGRpIxMjSUBrrr1gUtLWjZEm7ckMreuwe3bkHHjnD7tvIPODdX2fsByWDo6EjdrdxcOH0aqlWTjtXUpIH8K1ek7qu6uvR369aSUcvMlLw/gIwMaVlC587SuYHUZZs/XxrENzaW6gLJEBsaQoMGoKsreWgAL15IXb4GDaRB+qpVpc8zMiA4GOrVk4zxZ59BpUpSe0+eSPehYcPfb+FDpk+fzsSJE2Wp99J49OgReXl51K1bF4CIiAhatmwpd6XCw8P57LPPqF+/fonlCwsLuX79Ojo6OjRo0IC7d+9y+/ZtOnbsyO3bt2nbti3JyclcunSJ8uXLY2FhQZUqVXj+/DkXL15ECIGFhYVsEJKTkwkLC8PMzIzk5GRatGihIGoLIITg5s2blCtXjiZNmgDScxoaGkqjRo1o0aIF6enpxMfH06xZMwBiYmKoUaOGrCQdHR1NYWEhzZo1IzExkcuXL8uK3KamprIXFh4ejoGBgUJX8vr16yQlJdG+fXtiY2Np1aoVcXFxREREULlyZdq3b4+Ojg6PHj3i0qVLaGtr06FDBz799FMAHjx4QFRUFBYWFty9e1dJfPj58+fcKHqmf8fMzKxE4/ZPYvbs2Xh4eCgarI8Zd3d38vPzWbhwYZkage9FTg5MmSL9aH+fFfpH0qOHNIv4VncKd3fJ0I0e/ac3+euvvxIXF8fYsWMxMjL60+tXoaIkigzWv0aX8Pvvv//zKlNXlwxWMW/wH8miRdKA+tsMHy4tU/gAOP+XSxtUqPgz+dcYrD8VTc1/vrEC5YmEIho0+GvPQ4WKv4h/zV5CFSpU/PtRGSwVKlR8NKgMlgoVKj4aVAZLhQoVHw0qg6VChYqPBpXBUqFCxUeDymCpUKHio0FlsFSoUPHRoDJYKlSo+GhQGSwVKlR8NKgMlgoVKj4aVAZLhQoVHw0qg6VChYqPBgWD9fz5c44fP86uXbsUMmVmZnL+/Hm2bdtGWlpaqZXdv3+f/fv3K0RLLE5ERESpOmj5+flcvXoVLy8vJRHJtLQ0PD092bZtW6kCnkOHDmXQoEEKAQSvcIWf+ImtbOUJZYdlBsgjjzTeXN9pTnOAkmNeZ5HFXvbyIz9yilPvrLssUkklnzdhl5/zbgHVXHKZycwy84SHhzNo0CA8PDz+0Pn9r0RGRjJixAiF7/PChQuMGDGChISEMsua/R6T/vz580yfPv2921y1ahVbt25VSu/evTsvX75USk9LS6Nr165l1unl5cWa36O8nj9/ntTU1Pc+nz+LtWvXsmPHjr+83dLIzc3l5MmT78yXn5/PsWPH/tS2ZdWcKVOmiDFjxiip5vz8889iyJAhokaNGqXqEubn5wtra2vRq1evElVznj59Kpo2bSrMzMxKLH/u3Dnh4OAgWrVqJTZs2CCnFxQUCFNTUzFt2jQxevRo0blz5xLLv61WskwsE3VEHbFCrBDOwll8Lj4XoSK0xLJFhIgQMUgMko9viBsllnksHosvxZeij+gj1ov1ooVoIZyEU5l1l0Vv0VtcE9fkYyNhJPJFybpyReSJPLFdbH9n3dHR0cLOzu5/Prc/woEDB0TNmjWFq6urnNa/f39Rs2ZNcfXq1TLL3rx5UwghKcAU1xZ8F99995345ZdflNJjYmJK1OrLz88XMTExZdaZkpIiHj9+LISQlHPede4fgidPnojnz5//5e2WxtOnT0v9LRcnLS1NGBsb/+H2ilRzFDysn376iV/e1qwDJk2axI4dO5TiPr98+ZKzZ88CoK6uTmBgIOPGjSvRKk6fPp3Zs2crpMXExHD79m0AOnTowIEDB2SVlSJOnz7NJ598wsqVK/H09OTZs2eyYkppxBPPQhZyhSu44sp61rOIRUxlKgDHOMZ5zsv55yEJLHjiSTjhOOPMCU6QSiopKKvnfs/3WGONH34448xVrhJJJP74A+CGG4c5zBCGcJCDCCThgUIKOcpRRjMaH3zIJ59wwrnGNb7neyYwgUMc4hnPmMhEFrEIgGUswxFHFrKQWGLluh7wAIAkknDBhYEMxBNP0kkv8/78ldjY2BAUFERBQQEvXrzg+fPnNCgWr2vkyJFYW1tja2vL7t275fSi2Ok3b97k198VsPfv34+NjQ2WlpZMnTr1nerPnp6euLq6UlhYKItAPHr0iL59+zJq1CjMzMzIzMyUn8vXr1+zYsUKLC0tGTp0qBxKODAwED8/P86fP09oaCjTpk2T1aJmzJiBjY0NXbp0Yf369SWex8OHD5k2bRrW1tZMnz5d9vQGDhzIkiVL6NChAw4ODrLX6e/vT48ePbCxseGrr74CwM/Pj8DAQAD69++vUC4xMVGpzcDAQLp06YKlpSXOzs48ffoUkH7j7u7udOnShQ4dOsheUmBgIJMmTaJ37960a9eOjRs3ynUFBQXh5ORE165dZUX2H3/8kbt37+Lg4MC6desIDAxk6dKlcpmxY8fy4MEDfvzxR+Li4nBwcJC91D/CHxrDun//PsuXL39nvoMHD1K7dm1atGihkH748GH8/f3LLBsTE0Pjxo3l42bNmpUoM16cS1yiNa3R5Y1YRU96EkEEueQSSSS3eBOj3gsvAPrTn+Y0ZwELsMCC29zmMspSSWc5iz32Cmn22HMWyXhvZjMnOMEiFrGb3WxmMwDf8R3nOMd85hNKKL/yK81pTmMa44wzC1iANdbooss3fMNEJDl0M8zwxJNOdGIkkoR5HnnsRZL+KqSQUYziF37hMY/5iZ/4p6Curo6NjQ3Hjx9n9+7d/Oc//1H4fPXq1QQFBeHv78+qVatkNZzYWMkwZ2Zm8vjxYwC6du1KYGAgwcHB6OnplSjaW8TChQsJDQ3Fw8ODcuXKERcXR0FBgSx6OmHCBMLDwykoKJAl5I8ePcqNGzc4deoUzs7OTJ0qveBSU1NJSUmhQ4cOtGnThlWrVsnyWN988w2BgYGcOHECb2/vEodMZs2aRf/+/QkKCqJhw4ZylzUuLo7Xr19z/vx5unbtKhvs77//nm3bthEYGMimTZsASElJkbuicXFx5Ofnc/78eWxsbPD29lZq08zMjFOnThEcHIypqamc5/nz51y4cIGAgAC2bdsmh0ZPT0/H19eXLVu2EBwczMqVKyksLCQ7O5uZM2fi6enJ0aNHOXjwIPHx8cyYMYMGDRrg5+fHxIkTSU9Pl40iQEJCAq9fv2bGjBkYGhri5+cn388/wh8yWKampmU+NCB92atWreKbb75R+mz69OnMnFn2OExOTo4cYB+gcuXKpcoXFZFOOgYoeoNVqEJ5ypNJZqnlqlAFbbTRRx8dSg/Kn046NampkGaAgezZCATTmMYXfIErrgQg3SMffDDAgGMcoxrV2MMetNFGCy2qUY0a1OATPkEddfTRpyqSsosuuqxnPdvZzl3u8pSnCm3XpCYPecgylhFNNIcpeZzw72L48OFs3bqVvXv34uTkpPDZoUOHcHR0pG/fviQnJ3P16tVS60lOTmbcuHHY2dlx7Ngx2eN4mxUrVhAXF8fGjRtlwYviNGzYUB4jK87BgwcZMGAAGhoaWFhYkJCQUOK4V3FOnz6Nk5MTvXr14tGjR3KPo4isrCwCAwNZu3YtgwYN4vDhw/j6+sqfDx48GABzc3O55zBo0CBsbW359ttvFYxAcUoqV5y0tDQmT56MnZ0de/bsUbhXffv2RVtbGyMjI/nFANI4X9WqVdHS0qJWrVrcv3+fI0eOkJmZydixYxkyZAhJSUl/q5bhBw+RvH//fh49eoSDgwMZGRncuXOHqVOnvrd7WLNmTYWHIDo6+p3irY1pzCxmUUAB6kgP7DnOoYMOuuiigQZ55AGSd1KWESut/qMcxZg3YZSPcpTe9JaPKyLFVNdBh3TSKaCANNKoS13KI8mEteXd0lkppDCGMaxjHeMZTwQRvOCFgkH1wYeTnGQGMyiggP70/6+u50PTtGlTEhISqF+/vsLL5/Hjx6xbt47z58+jrq5O69aty3wZubu74+rqSps2bdiwYQPnz58vMd+gQYM4ceIEZ8+epVOnTkqfF5fbKk6NGjV4/lya8Cjyxj755BOFPOrq6rJeYFZWFgsXLuTSpUtoaWnRq1cvBS1FkPQVq1Wrxvr162UlqOLahRV/j72vrq5OQUEBANOmTWPEiBH4+/tjZWVVYo+ipHLFWbZsGba2tvTq1YuDBw+ybt06+bMKpUi+FU8vqldfX5/mzZsrTGRoaGiQlpYm3weASpUqkZ7+Ziji4cOH8rUWz/dHUfCwsrOzSUtLQwhBamqq/PDk5eWRmppKQUEB6enpZP6uXffo0SOFmYuiz4rnHzp0KGFhYXh7e7N8+XKMjIxYvHgxIM0YFT10hYWFpKamkpubS1ZWluxad+/enWvXrnHt2jUuXrxIfHw8nTt3LvOiOtCBL/mSaUzjMY8JJZRv+AY3JB22drQjmGDyyWcXu3iJ9BatRz3iiCOHsj24mczkN37DDz/SSWcVq7jDHbm7BrCFLeSRhyee9KAH6qjTn/7EEUcXutCd7tRCkncywoho3gifFj++z3300cccc6KI4iY3lc7nBjcww4wGNJC7t/80Dh8+rPCjAdDU1OTly5dcuXKFVatWKc0Ov42GhgaXL18mMDCQzZs3l5qvdu3aBAQEMGPGDE6dev8ZXEdHR3766SfOnDnD/Pnz6dixo5LQaKtWrfDy8iI4OBh1dXXS09O5cuUKnp6eXLp0SanOcuXK4eDgwJw5c4iJiSEqKqpUz7CITZs28fTpU+rXr0/lypWVBF/fB01NTa5evcr58+dZu3btf12+iCK5sJ07d5KYmEhgYCCxsbFUrVqV3Nxc/P39uXPnDu3bt+fs2bMEBwezYsUKeTzuk08+QV1dnUOHDsnj1X8EBYP122+/MWDAAFq1aoWDg4Pcpw4KCsLBwQFdXV1mzpzJwoULAam7V/xLcnZ2Zv369aSmpuLg4MCtW7coX748VapUoUqVKujr62Nubi6/tWJjY7l79y4gSZE7ODgQExPDgQMH5K7DZ599xs8//8zkyZOZM2cOXl5e8tulLI5xDHXU6UMf3HBjJCOZwQxAMlgNaIAVVjzkoeyR6KHHYAbjiCO72Y0BBtSlrlLdVlixkY1sYAOd6cxlLnOBC1SmMgAaaKCNNl3pii66jGUsAN/wDfnk05vedKMbwQRL9w1nznAGa6zlfMtZzihGYYYZTWiCNdbsYx9TmSp7b2qoATCOcZzmNHbYYYQR5pi/8/78FTRu3FiWedfV1aVSpUoAjBgxAn19fapWrcq6devYtWsXurq6bNu2jTp16gDg4uICSJ5OkdEoEts9c+YMa9euLdHT7ty5M2ZmZhgYGHDkyBEiIyPJyclh3LhxVKxYkSpVqjCmmOBs8fpbt27N3r17CQoKwtzcXDaKpqamdOzYEYCvv/4aMzMzzpw5g5aWFjt37mTfvn28fv2anTt3ylqGxVm6dCkjRoxg586d+Pr6oq+vD0gD05UrS8+MgYGB/Mzn5eWxatUqTp8+zfbt29HU1KRjx46Y/i46Mm7cONlTrVmzJgMHDlRq093dnQoVKnDkyBE8PDwYOnQoAFZWVnI9xe9z48aNsbd/My47ZMgQWc8xJCSEypUrs2rVKm7evCmn+/j4cP/+fWJiYqhQoQK7d+/m8OHDfPHFF6xfv17Ot3fvXuLi4v4UgwXFljV8zFSuXFk4OTmJrKysv/tURA1R44O3ESEixEAxsMw8YWFhws7O7m9b1vBHefbsmXB2dhabNm36IPVnZWWJlStXismTJ3+Q+lX8eRQta/jXyHz9HYv5SsOUUuS3/iQe8YgVrGA2s8vMZ2ZmxpEjRz7ouXxIkpKSsLS0fOeY5f9Keno6FStW/HM1LVV8UP41BuufxIeepatJTbxRnsr+t9GiRQulpTB/Jnp6eowfP/6D1a/iz0e1l1CFChUfDSqDpeKDkZ2dLc8og7QnLzQ09L3LR0ZGlrgvsDipqanyYtO3efnyZYlT/m/j7Oz8XnWfPXsWT09P9u/fz8GDB99Zb9HSi8WLF79zsXPRcooiVqxYwY0bN5g1axZPnrx7H+z/F1QGS8UHY8+ePfzwww/ycZ06dahatep7l09KSiIyMrLMPGPHji11senAgQN58ODBO9vx8/MrMX3o0KEKM1tffPEFZmZmNGvWrMTZwLcxNzfH0NAQKysrqlevXmq+nJwceRayiI4dO1KjRg1sbW2V1oL9f0ZlsFR8EPLy8ti2bRsBAQE4Oztz7do1nj17xqtXrwBp3563tzejR4/mxIkT8lqj9PR0lixZwrhx4xQiOuTn5+Pr68vo0aM5fvw4QgiuXLlCZGQkS5cuxdnZWWGB4oULF7h16xbffPONvCUkJyeH7du3M1XpG+UAACAASURBVHbsWM6cOaNwvoGBgQwdOpRNmzaRn59PWFgYUVFRfPfdd0yaNEnOs2TJEjZs2CDvYzx//rzCyu/Lly+za9cu8vPzOXDgAFOnTuXs2bNylBEhBD///DMDBw5k+PDh3L9/H09PTx4/foyzszObNm0iIyMDPz8/nJ2duX79eqkRSv6/8q9Y1qDin8fq1auFq6urSE5OFjk5OcLV1VX4+PgIIYT46quvxLp168T9+/fFoEGDxNGjR4UQQtjZ2YktW7aIqKgo0apVKzFlyhQhhBDffPONmDx5srh165bo16+f2LRpk8jJyRH29vbi2LFjIjk5WaHtrKws0bFjRxESEiKePHkihBDC3t5e7NixQ9y7d0/Y29uLkJAQIYQQVatWFa6uruLevXuiV69eIigoSGRnZ4uuXbuK06dPy5Eazpw5I54/fy4iIyNFixYtRF5enkhISBDNmzeX2x0yZIgICAgQr1+/FqdPnxYpKSni0KFDwt7eXgghhL+/vxg1apRITU0Vd+7cEY8ePRLJycmifv36Ijk5WaSmporU1FQREhIiUlJSxJYtW8TIkSM/4Lf0cVBitAYVKv5MKleuzCeffIK+vj5aWlpyelZWFhcuXEBNTY3jx49Ts2ZN9uzZQ3p6Og8fPmTEiBE0a9aMQYMGyWX8/PyYP38+jRs3Zs6cOfj6+qKlpYW2tjZVq1aVF2MWUaFCBbS0tKhWrRp6enqkpKRw69YtMjIyOHnyJLVq1WLPnj0AqKmpMWfOHIyMjHB0dOTMmTNoa2vL5WvUqAFIizR37NjB2rVryc7O5uLFi9SqVQsDAwMiIyNJT0/n0qVL2NraoqmpiZaWFmvXrmX//v2EhYWRk5ODnp4eEREReHt7U7VqVQwMDKhSpQoaGhro6+tTuXJlKleuTFZWFj/++CPBwcHvFXfq/wuqZQ0q/nIyMzMpKCjA0NAQAENDQ3R1dcnOzlYwbDo6b/ZLZmRkyHvdPvnkE7lr+b6kpaWhrq6u0GaRIVJXV0dXV4rsUbFixRK7YIWFhQwcOJCVK1cyePBgJk2aREqKFHpoxIgRbNu2DWNjYxwdHVFXV+fBgwe4urqyZs0a6tWrx8mTJ8nIyMDc3JyAgAB27NhB586dWbt2LW3bKu4pDQ8PZ8WKFSxduhQDAwOFcDz/31F5WCo+GEZGRty5c0dpFq969eoYGxuTl5dH9+7dsbGxQU9PDz09PbS1tbl06RKpqamyBwTQq1cvPD09ycvLw9PTU97yU69ePW7dukVJGBkZER0dLecrqt/W1hYrK6t3TgAUL1+0z9XCwoLU1FSCgoLkfA4ODhw5cgRPT09GjpT2k966dQsjIyNMTU05ffo0jx49AiA+Ph49PT3mzp3LkCFDiIqKQltbGzU1NXnx840bN2jWrBktWrRg//79ClF0/7+jMlgqPhht27bFyMiIHj16cOHCBYyMjOTZsvXr1xMZGYmtrS329vZysLxNmzbx888/M3jwYPr37y97F/PmzePVq1fY29ujr6/P2LHS/syxY8cSEhKClZWV0hKGKVOmEBAQgJ2dHQDbtm3j1KlTdOvWDQcHB+7duwdA+/bt5TLVq1fHyMgIgAkTJhAUFISNjQ26urqMHz+e7t27s2DBAqZPny5fS4UKFRg+fDhNmjShUaNGAHTr1o1KlSphbW1NeHg4Y8aMkTckd+vWDVtbWx48eMCIESMAKQbWmDFjWLRoEY6OjqSkpGBtbU1aWhqOjo5/+nfzsaKGNOguB/JSoUKFin8as2fPloIx/t0nokKFChXvi8pgqVCh4qNBZbBUqFDx0fCvMVh37tzh9u3b7xWONTU1lRcvXgCQmJjI69evAUlU488iIyOj1HjcgMKq73eRm5tLUlISIIkRFEVjjY+PL3OvXGFhIbdv337nPra/m927dyOEICUlpcRwOC9fvmT//v08fPiQEydO/A1nqOKfgoLB+vHHH2nXrh3NmzdXyHTw4EG6dOnCF198oRC0vjiFhYUMGzaM5s2bM3HixBLzjBw5kj59+pT42datWzExMaFFixYMHjxYVjIp4tWrV7Rq1Yoff/yxxPLt27fH29ubvDwpVntCQgJ9+/alYcOGNGzYEHd3d/mzXbt2yWok48ePl2eLSou7dOfOHbp3706jRo1o1KgRK1aseKdhPHv2LKtWrSr18+XLl3Po0KEy6yji1q1bTJ48GYAtW7bI5caOHau0abY4+fn5eHt7K8yC/RMp2iaTkJBQYjjf3Nxc4uLiyMjIkA33X8XUqVO5eVM5LLUKKVpr9+7d/9I2FQyWpaUle/bskQPIF9G4cWN+++03KleuLP/o30ZNTY2xY8cyb948nj17pvT5vn37yMrKIjk5ucTyLVu2JCQkhGvXrmFhYaE0a+nm5oaRkVGpKiaffPIJCxYsQEtLi4KCAuzs7Gjfvj3Xr18nMDCQ69evs2DBglJvBFBirO2srCysra1xcnLi5s2bBAQEEBAQwM8//wxInlROTg6PHz9WkHiysbFh7ty58vHLly+5evVqiVp6hYWFCjvyMzIySr3OCRMm0L+/FNLZ29tbnlrPyckhKipKQcShfPnyLFiwQA5N/FcTGxvLzZs3OXz4MNu2bSM9PZ2EhAQ2b94sr0sCsLe3R01NTal8QEAAz549Iz8/H11dXSIjI+nXr1+JbYWHhxMXF4eXlxf79++nsLCQqKgotm3bJt/zzMxMTp8+LZe5fv26/KwXl5tLSEjg2rVrJCYmEhoaysGDB/H29pb3OyYmJrJjxw6FoJEBAQEkJyezefNmee1WSbx8+ZKdO3fK0mUgKaLHx8ezd+9ehX2VxRFCEBoayk8//cSuXbsUxC4uXLjA4cOH5ZdokV7olStX2Lp1a4nP0t27d+WlJCAJgly8eBGA4OBg1q5dS0hIiMK53Lx5k/Xr17N582ZevnzJxYsXuXbtGt7e3ly4cIGCggJOnDjB2rVruXLlilzu6dOnhIWFyccXL16UezixsbFs3LiRDRs2lGobiqNgsExNTZW2OAA0atQIIyMjpYcqKiqKYcOGAZLB6tixY4k7y1+8eMFvv/2Gm5ubQvqGDRtk8ckWLVrIK5mbNWumIEgQFBSElpaW0org0jhz5gwvXrzA1dUVbW1tateuzezZs0sUiS1OadJPVatWZdSoUWhoaNCgQQNcXFzkuhYtWoSdnR0TJkygR48estDCsWPHmD9/PgDz589n1KhR7NixgxkzZijUn5OTg5OTE/v27QNg5syZjBw5ktGjR+Pq6qp0PqtXr8bLSxKasLe358mTJwgh6NOnD56envTt25cVK1a813360Jw8eZKBAwdy/fp1wsLCcHJyYt68eRQUFNC5c2fZwE+dOlXBY83Pz2f06NFcvXqV6tWrExwcTPny5cnJycHCwqLEF+KGDRsYMmQIaWlpbN68maFDh7J+/XrS0tKwtLQEpG74d999J5fZtWsXISEhwBvhVpBimO/atavEa1q6dCnz5s0jPz8fe3t7rl+/Ll+Di4sLQghGjhxZoqLPiRMn6NmzJ5mZmQwYMEBuY+PGjQwePJjk5GS8vLxKfLHu27ePFStWUK9ePZ4/fy6LxXTp0oXg4GCio6OxtpY0Ae7fv8/gwYPZtGkTWVlZtG/fXskI5uTkyJu6AdasWUNUVBR5eXkEBQVRq1YtDhw4IK8Ti4qKYvz48RgYGCCEUNiYXsSLFy+IiIjg888/59dff5V/7zdu3OC3336T861evZrY2FiSk5MZOHAgurq6VKhQ4b2GZP7Q1pwaNWq8V/ja6dOns3jxYiUFElNT0xJvpJubmxy2NjMzk0WLFuHv769w0WVx7949rK2tFQxs27ZtKSgoKLMLVVpdXbp0UUizsbHhwYMH8rnXqlWLHTt2kJ+fT5MmTZTiKx06dIgjR47w+eefK6S/ePGC3r174+zsTL9+/YiKiuLx48f4+PgA0Lt3bwVPpDSK9uS9fv2axMRE+vfvj6ura4ley19Ny5YtmTNnDtnZ2VSpUoW4uDgMDAyIiooiKChI6fnJzMzE0dERBwcHedX4kCFDuH//PqGhoTRr1gx/f39GjRql1JajoyMTJ07E1NSU/v378/DhQ9TU1ErsNbwPtWrVolatWnTv3h1TU1MKCwvZs2cPXl5eqKur8/r1a7y8vDA2luTe3NzcaNWqFRUqVODYsWN06NBBob4dO3awZMkSLC0t6dChA9OmTZOFZR0cHJg6dSrPnj3D3t5eFnop4uHDh+jp6dGiRQtZLOLs2bPUqFFDXlh68eJFIiIiUFNTo0KFCnIv4MSJE0RFRcnnCdC8eXMyMzOJi4ujTp067Nu3j4iICDQ1NXF3d+fSpUs0adIEX19f8vLyePjwIZ999hmNGjXiyy+/BKQXS6VKlRT2fE6bNo0LFy5gbm7OypUr8fDwKPX+PnnyBG1tberVq0fLli3f6zv5QwZLT0/vnQbr9OnTPH36lMLCQq5fv05GRoa89aC4egdIIUccHR0ZNmwYXbt2BaQVwJ07d+bGjRvEx8eTnp5OYmIitWrVKrXNqlWrKil0JCYmkpOTI6uUvC9Vq1ZVkm+KiYmhSpUqskEo8sw0NDSoW7eu0laRpUuX4ujoiI6ODtOnT6dnz54ALF68mOHDh8vdnICAAKKiouRtJ1lZWVy7dg0DA0VR2LcRQjB48GDy8/OpWbMmycnJJCUllXmP/iqKVqpXqFABAwMD+Vp0dXVLnJRITEwkJSUFGxsbOW3GjBmkp6fTqVMnqlSpUuo4alFb1apVo1GjRvL3U9RW9erVFV6QpQX+Ky09MTGR5ORkBWm7+vXry38XKZRXr169xGu7du0aDRs2lMsVHxsrKlutWrUSPciJEyeydetWBg8ejI6ODt7e3oSHh5OYmCgHOWzUqBH5+floamoqqKWXdj7Dhw9nx44dmJubY25uTuXKlcnIyKB9+/YMGzaMevXqkZubS0pKCnZ2dmRkZODi4kJ6ejqbN29WuHaQZP/s7OwYOXIkdevWLfUlUTSsZGJiwpw5c1i4cCEJCQn88ssv7+xFffBZQm1tbRo2bIi3tzfHjh3jxYsXJe4+z8vLY8CAAXTp0kXBVW3UqBGpqal4e3tz9epVoqOjZTe8NCwsLIiJiVEYuN+/fz+WlpZKXt67sLa25ty5cwrjAPv376dbt27ycfExi7i4OKXNqj169ODSpUts3LiRKVOmyD+IRYsWcf36ddlzbN++Pc2bN8fPzw8/Pz9OnTolbyspi9OnT1OxYkX27duHh4cHr169+lPFK/9KGjVqxObNm+nTp4/cRfD392fNmjUMGTLkD0Xf/PzzzxXGjoo/h3Xq1JG92eLp1apVk8eq6tSpg6GhIVOmTGHZsmUsW7aM0aNHv3f7tra28jjp2bNnlTz3stDS0mLChAmcP3+eBg0aEBwcjIODA2pqavK5LFu2DHPz95d4+89//oO3tzdbt26VPdbTp0/ToUMHXF1dad26tcIkh5OTE8ePH+err77C19cXdXV1BS/+8OHDODo64uLiQu3ateWxwyZNmsgz1a9fv5aFkQsLC7G3t8fPzw93d3d27tz5znNW8LD27dvH2bNnycnJwcXFBVtbW2xtbQkPD8fLy4ukpCSWLl1K+/btGT9+PGFhYcycOVOe5Vm8eDFhYWFER0fj4uLC1KlTadeuHe3atQOkfnBMTAzTpk0DYMmSJRQUFDB//nzmzZvHlStX+OKLL3BxcaFatWq4u7vLfWiQZjFfvnxJjx49yrwofX191q1bR+vWrRk0aBCxsbHExsYqDKy+L40bN+a7776jYcOGDBs2jPDwcNLT0wkICJDzhIWFyUKZPXv2pHz58gp1DB06lI4dO/L48WPq16+PhoZ02ytWrCjLo+fk5PD111+zYsUKxo0bR5s2bbhy5YqsG1cWTZo0ITg4mFWrVhEcHFyqsvHHQps2bdi8eTP9+vVj7969DB8+nO7du1NQUPBOb7MsNDQ0GDRokNxVKz5eO2HCBPr06YOOjg7Vq1dHT08PkFSkFy1axPfff09gYCBLly5l4sSJaGtrk5GRgb29PRMmTHiv9seNG4erqyt79uyhsLCQJUuWvPe5z549m5s3b/Lpp5/y7Nkzli9fTsWKFbGzs6N79+5Ur16dpKSk9x42Aan30LhxY0JDQ+XxNCsrKxYtWkSfPn3IzMyU90Zu2LABHx8fDAwMSEhIYMuWLaipqTFo0CBsbGzo2LEjY8eOpXfv3ly+fBkhhHx/9fX1adSoEVZWVggh5Be6n58fq1evpm7duiQkJLB8+fJ3nrPCXsK7d+8qWFRDQ0MMDQ158uSJQjdHV1cXY2NjXr16RWxsrNz/DA0NVdhZ3qpVKwVp8szMTGJiYmjVqhUgrSMSQmBoaMjt27cV3n4VKlSgTZs2CiebmJhIXl4eX3zxhdKF1K5dm5MnT9KwYUNZCjw5OZnw8HA+/fRT2rRpIw/qP3r0iIKCAmrXrk1UVBRGRkZUrFiR0NBQpTaLePjwIZcvX6Z69eqYm5vLRsnNzY0mTZpQt25dqlevTtOmTQFpvdTLly+pX78+165d49atW9StW5fWrVujqanJ/fv30dHRoUaNGuTl5XHx4kXat2+PpqYmcXFxhIWF0bhxY4yNjcnIyCA+Pp6mTZvy8OFDNDU1MTAwwNTUlODgYCpVqsTTp08JCQmhVatWpKSk8OWXX6KpqcmdO3fo0qULiYmJ73gU/tlkZmaipaUlG/s/WleFChUUJONBWj6hpqam9MIpiZcvX1KhQgW0tbX/6/azsrLeSwz4bVJTU1FTUytxWOPp06dUq1ZN6Zr+V9LS0pTaycjIIDc3951RLkoqC1I02bdnrLOzs8nIyCgzhDS82Uv4r9n87O7uTn5+PgsXLlSIqfShcXNzo2nTpvJs6V/FsmXLCAwMLDO4W25uLt9++y0aGhoq7T0VHzVFButfE8Dv7/pBjh49+m8RCejevTuzZs0qM4+WltZH/yJSoaI4/xqD9XdRNOvzV/O+08AqVPyb+NfsJVShQsW/H5XBUqFCxUeDymCpUKHio0FlsFSoUPHRoDJYKlSo+GhQGSwVKlR8NKgMlgoVKj4aVAZLhQoVHw0qg6VChYqPBpXBUqFCxUeDymCpUKHio0FlsFSoUPHRoDJYKlSo+GhQMFiBgYHMmTNHKYJiVFQU33//PSNHjixVikcIwebNm5kyZUqp6jQbN25UUC0pzvXr1xkxYoT8v0h7Ly8vj40bNzJp0iS2bNlS6oU0aNCAQYMGyQEE88lnDWvoRz9GMIKTlB43qogUUgghRD7exS5Ws7rEvNFEM5GJ9KIX7riTRlqJ+d6H85wnlTeSUYc5jEBZ6qk4WWRhiWWZecLDw+nduzdDhgz5n8/tr6AktaLiPHv2jNDQ0HfWs23bNvnZGzp06D9KQDYoKIisrKz/qszx48cVZPXejpg7ceJEjhw5Qq9evYiKilIqn5KSIivpvA9z587l1KlTgKRi9TahoaGMGzdOKX3hwoUcPnz4vdv5IygYrPj4eJo0aaIkcZSYmIiBgQHnzp1T0N4rjhCCpKQkPv30U4KDg5U+v3btGps2bVIILfx2G9nZ2bi4uODi4iJH/nz9+jXPnj2jfPnyXLhwodQLycvLw9vbW44q6oQTwQQzl7nYYcdUprKTsmNG3+UuP/GTfGyLLYMZrJTvKlexxZaGNGQFK0gnnba0JZdcpbzvwwpW8JA3AfunMpVCyo7Jro02v1F2OFwzMzM8PDxkDbh/KiWJLhQnOjpaloMri6ysLDIzMwEpImhpYhJ/B9999907r/NtZs+eLV8PKEqRAfzwww907dqV3bt306RJE6XyhYWF/5VK1KRJk+SY8CWJVrx+/VpBi7GIsWPHKikEfSgUDNaoUaNwcnJSymRnZ8fo0aOVwpvGx8ezerXkgZQrV4758+fL8duLk5+fz6xZs5RiWB8/fpxjx47Jx9ra2lSsWBETExNq1KgBgI6ODnPnzqV169bvfVFXuMIJTuCNN61pjRNOeODBfCSdwN/4DR985Pw2SAotP/Ij5ziHAw744ksQQRzggFL9i1nMSEbigguNacwa1lCFKmxnOwAd6chc5mKBBdOYxgskg5FMMm64YYMNk5nME55wjnOEEYYLLvSlL1548ZjH9KMfU5kKgCOOWGGFPfYcQvI8c8nFFUm38AY36EpXLLFkGMO4x733vlcfktzcXDw8PLC0tGTYsGGySkxWVhbu7u5YWFgwceJEBcEMT09PunbtSr9+/WSxgh9++IGgoCAcHBzw9/cnLy+Pn3/+GVtbWwYMGPBO72vw4MFYW1vTo0cPfH195fSBAwdibW1Nz5498fPzA6QwwN26dWPKlCm0bduWyZMnlyhsOnToUBYvXkzHjh3p1asX9+/fJzc3FxsbG9lQvnr1im7dunH06FFu3LjBuHHjSvR2Y2NjmTx5MtbW1syePZv09HR8fX158OABX331FePGjWPNmjU8ffoUBwcHvv/+e9LT0+nfvz/dunVj2LBhsghqacTFxdGnTx8ePHiAj48PNjY2WFpa4uLiIhvFLVu2EBkZqVAuPT0dJycnJWchPDycAQMGkJqays6dO0v8Dn755RdsbW2xsrKSNTo3btxIly5dsLS0xM3NjYKCAgB+/fVXunTpgpWVFbNnzy5TREW4ubmJInJzc8Wnn34qSsLExETcunVLPr5z546YP3++Qh5/f3/Rv39/hbQlS5aI7du3i+vXrwszMzM5fd++fcLHx0cIIcTJkyeFnZ2d6N27t2jZsqUIDg5WqGPnzp1i9OjRJZ6XEELUrVtX/nuL2CL6iD4Kn2eKTKEttEWaSBOLxWKxQWx4U1ZIZUNEiBgkBsnpnsJTLBKLlNpqIBqIUBGqkLZILBKTxCQhhBBVRVWxUWyU0z2EhxBCCGfhLAJEgBBCCG/hLeYL6d71Fr3FNXFNrstIGIl8kS8fp4pUIYQQGSJDtBFt5L+biqby30X5T4qTwkW4yGWjo6OFnZ1dCXfsw7Nv3z4xcuRIkZ+fL86cOSO6du0qhBBi69atYtq0aaKwsFD4+voKNTU1+Vw7d+4sMjMzxYMHD0Tjxo2FEEIEBweL4cOHy/UeOHBAfP3116KwsFAkJyeLzp07CyGEWLdunfDwkO51z549xY0bN4QQQqSmSvcvOztbmJmZicLCQoX0rKwsYW5uLoQQIi0tTQDi3LlzQgghHBwcRGRkpNK1derUSbi5uYnCwkKxadMmsXDhQiGEEGPHjhUHDhwQQgjxyy+/iHnz5gkhhOjcubOIi4sr8T7Z29uLq1evCiGEWL58udi4UXp2TExMxMuXL+V8xZ/xvLw8kZmZKYQQIikpSXTr1k2p3qdPn4rmzZuLK1euiHbt2onbt2/L11jEwoULxd69e4UQQkyaNEkEBEjPp76+vkhKShKdOnUSJ0+eFEIIcfbsWTFgwABx+PBhYWVlJZ4+fSqEEGLGjBli3759Cm3n5+eLhg0byvc6OztbCPHmngshxOTJk8Xp06eV0idMmCDf/yLc3NwEIP5QxNEGDRqUOiZVxO3bt7l06RIHDx5U6mcXCUACdOnSRZY9Cg4OxsPDg86dO/9P56WBBtlkK6S95jUFFKCO+v9U57vqzyYbjWIBXPshaQ064cQ4xjGDGfjhx0tesoMd5JFHDDF8R9n3D6SxtOMcp4ACHvCAOOKozpug/fnk44YbN7mJJprEEfeHr/HP4ODBg/znP/9BXV2dTp06cf/+fV69eoW/vz8zZ85ETU0Ne3t7dHR0AElFpU+fPlSsWBFDQ0Pq1q2r9MYH2LNnD8+fP2fwYKm7fuPGjTJFNnx8fDh8+DD5+fkkJiYSExND48aNZem5/Px84uPjuXv3LjVq1KB27dpyF8fc3Jzw8PASI7wOHjwYNTU1zM3NOXBA8sQnTJiAu7s7Dg4OeHp6yuml8eLFCy5dusTSpUsBSWiiXLlyjBkzpsxyGhoaeHh4cOnSJcqVK0dYWBivX79WEtBISkrCwcGBkJAQWXEoKSkJV1dXEhISSE9P59GjRwwYMECpjY4dO+Ll5aWgFRgSEsKdO3e4ePFimUIa6urqWFtb06lTJ/r27cvIkSPR1tbm3r17/Pzzzzx+/JiUlBSqVKmCpaUld+7cYd26dTx58oRnz55Ro0aNEruZHzxEcnR0NI8ePaJt27ZkZ2cTGxvLqFGj2Lx5c6llvvzyS+7evfs/t9mKVoxlLJlkooP0YzjBCepTHx10qEQl0kkHpMHrFFIAKEe5d44dAbSmNYc5TGfeGNTDHJa7aCAN4OuiyzOeUZ3qqKOOHnqsZCW66AKghlqJ7RYdq6NODDH44cdRjlKOcnzBF+SQo3A+G9lIHerwAz9wjWsMZOD/ctv+dGrUqCGP2+Tn51NQUEDFihUV0jMyMuSJEn19fYXvPSUlBT09PTIzMxW6CPr6+vTu3VtBxLc04ZG4uDi8vLwIDAykXLlyNG7cmJycHGJjY/Hx8eHEiROUK1eOBg0akJsrjUEWjYOC9MMr6ra8TVG+4nlatmxJamoqe/fupWbNmtStWxeQhkxECV1LHR0dqlatiqenp6wIVKR8U65cOYXrLq4BGBgYKEvXZWdnU716dfLz85UMVs2aNenSpQvfffcd69atQ01NjXnz5snDLOvXrycsLKzE65szZw7ffPMNBw4ckF8qrVq1Qk1NjV9//ZXp06eXWK6I9evXk5SUxO7du+nTpw9nz57F1dUVT09PjIyMWLRoEa9evQIksdzt27djaGjIt99+S05OTol1KoxhXb9+nUOHDpGXl4efn5+snpyQkICfnx9paWkEBgYSEiLNpN2+fVvWGAQ4deoUly5dIikpCT8/P168eEG/fv0IDw/n0qVL7Ny5kyZNmsjGateuXbKK7qFDhzh58iTHjx9X6usfPXqUy5cvEx8fj5+fH+np6WXeqCY0c8tw8AAAIABJREFUYTSjscKKfezDAw9mMpMf+REAa6zZwx4ucpF5zJONRTOaEUUUxzhGAgml1v8t37KXvbjgwjGO0Yc+VKKSPECvhhrLWEYIIXzHd/ShDwBf8RVuuBH9+79jSON3ppjihRdnkPQdW9GKDWwgggg00eQJT7jGNRaykOcoD6JqoMEtbhFOOEt4f627D42joyNr1qzh7NmzzJs3DysrKzQ0NOjXrx/Lly/n4sWLzJs3Txa37d27N3v37uXIkSOsW7eO8uXLU6tWLYyNjYmMjOT48eMkJiYyfPhwVq5cSXBwMA8fPmTXrl0KP+biaGho8OzZM65evcqSJUtksVQNDQ2ePn3K1atX+f777xUk5v4o48ePZ/To0Tg7O8tprVq1Ytu2bUpjQVpaWnTp0oX58+dz7949rl69Kut8mpqasnnzZll5/PPPP8fHx4eoqCg0NDR4+PAhV65cwc3NrdQxHzU1NVatWsVnn33GqFGjKCwsRENDg8uXL3Pq1ClZNbokxowZw7Bhw7C3t5d/c1paWvj4+BAaGlqmrmJaWho7d+4kJyeHBg0ayN6Ympoaly9fJiAggD179iiUuXz5MocOHWLfvn2l1qsOLOjQoQNdunQhIiKCq1evYmFhwePHj6lWrRqGhobExcURHBxMixYtyMrKQk1NDWNjY3JyckhPT5d1BgMCAsjNzcXIyIjHjx/TrFkzBX0yNTU1dHR0ZIn6Fy9e8Omnn2JoaMjjx4/x9/cnPj6e4cOHM2TIEPlN4+fnR7ly5ahTpw6PHz+mZcuWssUvYvXq1Qqioz3ogR56nOc86qizhCW0pz0AeuhhiCH++NOHPjShCW1piyaatKENoYTyKZ9ShzoYYEBd6iq0pYsugxnMfe4TQQSd6MQqVsldwpWsZDnL2c9+xjOenkjS9BZYYIghe9lLFFGYYUYtamGCCVlkEUEElljSgQ484AEJJNCNbtSiFn74YYopdthhjDHlKMd2tuOMM81pTjLJXOACE5iAAQaYI832PH/+nBMnTvDVV1+V+hB8KGrVqoWVlRUHDx7E3NwcV1dXypUrR7169TAxMWHv3r307t2b5s2b07ZtWypWrMjAgQM5fvw4urq6eHh4oKmpiba2Nq1btyY0NJTPPvuM1q1b07NnT06fPs2JEycwNDTE2NgYNTU1atasSZ06dQAwNjbGwMCAevXq4evrS/PmzenduzfNmjWjVq1a1K1blwMHDmBiYoK9vT3NmzdHR0cHDQ0NBQXlOnXqULNmTYVrU1NTw8TEhIoVK6KmpkbFihUxNjYGJGn4Xbt28csvv8iG1MzMjJSUFG7cuKHU1bGzs0NHR4fdu3dz//592rVrh56eHu3atSMpKYl79+7Rtm1brK2tuX79Omlpadjb21O+fHmOHDmCvb09rVu3xszMDHV1dYVz1NTUxMzMDBsbG1JTUykoKMDR0ZGLFy/y4MEDpk6dSq1atWRp+4YNG1K1alXU1NRo3749xsbG6OvrExcXR8OGDalcuTLNmzenX79+XLlyBX19fapUqUL9+vUVtAWFEJw6dYqAgADU1dWZPXs2lStXpkOHDpw8eZJnz57JCtFGRkZ07NiR48eP8+LFC6ZOnUrt2rWpV6+eXN+pU6dkY68w6P6x0rlzZ9GnTx95IPLvpIao8UHrzxE5Yq1YK8aJcWXmCwkJEfb29mLatGkf9HxUvOHBgwdi9OjR4rfffvu7T+VfxZ8y6P5PoqS1X38XU5jy7kx/gEwyUUedZZStOdi2bVulxYYq/o+9M4+rKf//+DNljez7LkbIiET2hClLsozsZBlraKzN2PcwM/wwaGw1BiFTlDV7ZmQZSmMpWyQJbRTV7fb5/XHmHl33VsxMlvmep0cP95zz2c65977vZ3u/X3lLcHAwLVq0YNiwYR+6Kf9J/jMG62NiJjPztPxSlGIsY3NPqPDe6dev34duwn8axZdQQUHhk0ExWAp5xqtXr7RcS7LD09NTXgnLSmpqKsnJyfJxZmYmzs7OxMbGMm3atFzLvX79Ou7u7pw+fZrNmze/W+PfkeXLl+e4F+xNfH19OXnyJABz5swhMTGRxMREvvnmm7fKf/HiRXmF/X8JxWAp5Bm7du3iu+++yzXd5cuXiYrS3Ubi5+fH4sWL5WMDAwO+/PJLihYtSufOnXMtt1y5crRr146aNWu+k2vX3yEoKEivn112VK5cmXLlygFgbm5O/vz5efXqFUeOHHmr/KVKlZL3eP0voRgshTxBpVLh5eVFQEAAY8aMITQ0FJB2So8ePZqNGzdq9b6ePHmCi4sLbm5uREdHA7B582YOHz7MmDFjuHTpkrxPcPTo0cTFxZGRkUFqairffvutXI5arWbGjBkIIfj9999Zu3Yt7u7u8gZFgKVLl3LixAmcnZ1ZuXKlTi8wMzNTLkODm5sbKpWKo0ePMmTIEEaNGiVHNshKRkYGM2fOZPfu3fTv35/t27cTExPDhAkTmDdvnmzU4uLi5NeRkZE6m1NTU1OZPXs29+/fJyYmhnnz5tGjRw8mTpwISD5++hyU/+soBkshT8ifPz89evTAxsaGefPmYWZmxs6dO1m3bh0zZswgLS0NNzc3Of22bdsYOXIktWrVYu7cuYC08bRNmzbMmzcPc3NzjIyMcHNzw93dnQMHDnDw4EEKFSpEcHCwbBADAwOJiorCwMCAsmXL8sMPPzBhwgSmTJkiRy7Yu3cvnp6ezJo1i/DwcJ0NjPny5eP27dvyBs7z589z9epV8ufPT4kSJXB3d2fatGksXLiQe/fuaeXNzMxkxYoV3L9/n7lz57Jo0SJcXV3lsCyrV0vRQC5fvsyNGzcAqSeZ1WgmJCTQvXt3LCwsqF69OosWLcLU1JTt27fL7kj37t3L1eH5v4hisBTyjOLFi1O0aFEqVKhAwYIF2bFjB7Vr1+bo0aMYGhri7+8v79AePHgwFhYWODs7c/bsWQBKlCiBsbExFSpUoFChQlSvXp0LFy7g7u5ObGysHIPJ2dkZLy8vQJoP02wpqFatGr6+vnz//fdkZGRoRQb5+uuvqV27NgMGDJANU1aGDh3Kzz//rFNm9erVOXjwICtWrCAtLU1vuKTChQvz9ddfY2ZmRrt27bC1taVhw4b0798/1+038fHxdO3alTlz5si+tpUqVWLPnj0cO3Ysz4e2HzuKwVJ4b8TFxVG5cmVq1KhBzZo12bBhgzzs0sznFChQIFs/sqVLl3Lnzh0mT56Ms7MzcXGSD2jv3r3x9/fn2bNnXLlyhQ4dpHBBgwcPplKlSixYsIC2bdvK6bPWV6RIEb2B9bp06cKZM2eIj48nMDAQR0fJvWrUqFEULVqUOXPmYGdnpzfWWIkSJWS/wCJFish1FS5cONdFiAIFCmBkZCQPiwHZ9+/EiRN8/vnnb7WQ8V9FMVgKeYapqSkRERFyfKjBgwfz559/0q5dO+zt7TE1NdVyJdGX/9atW3LUzT///BMbGxvKli2rNYwzNjamTZs2jBgxgr59+8pOww8ePMDGxga1Wv3OETGNjIzo3r07w4YNo0uXLrJT8a1bt7C1tcXIyEiOivtvUrRoUQ4ePMhPP/0k9/AiIiKwtrZm1apVVKxYUfaH/F9EMVgKeYa1tTWmpqZ06dKF3377DWdnZ8zNzenbty+dOnWSI9vWqVNHyw9NE87E0tKShg0b0q1bN06ePMnMmTNZsmQJTk5OfPHFFzRo0EDOM2rUKJKSkuShW758+Zg/fz69evVi4sSJjB07lipVqsjlaqI7FCtWTKucrAwfPpykpCStUC9LliyRg+oNGzaMGjVqAMh+iAYGBlpBLE1NTeV7K1iwoOxHW716dTncS+PGjSlYsCAFChSgadOmFC1alICAAE6cOMGlS5f4+eefadu2LQ4ODnTt2pU6depQpkwZateu/TffmU8XAyRfQtzdc3bzUFBQUPhQuLm5sWzZMqWHpaCg8OmgGCwFBYVPBsVgKSgofDLoGKyXL1/y4MEDnYSauNdZddL0ERcXpyNnFBMTQ2RkJJGRkdy/fz/H/NHR0Vr+YxqioqJyjAq5ceNGNmzYQHp6unwuPT2dq1evEhkZqZX22rVr8kbDQ4cOkZCQAKAjb5aV1NRUrly58tb+YpGRkTlu7AsODn7rMNBxcXGyy8bly5flSLB+fn45at2pVCo2bNjAxo0b36qe98XBgwfzZIVN4b+PlsFydnamadOmNGzYUCvRqlWrqFevHg0aNODOnTt6C1Kr1Xz22Wc0bdqUcePGaV3r1q0b48ePx9XVlSlTpujNf/bsWWrVqkWTJk3YuXOn1rUuXbrg5uaGi4sLTk7645XPnTsXMzMzeZk8MDCQatWq8e2339KlSxfatGkji8CePn2ao0ePArB27Vqt8/rYs2cPlStXZtGiRbRt25auXbvm6jf25MkTeSezPvbu3ftW4qAgGesNGzYAkiSUxmgGBwfLccj1oYlhrtk5/rEQHh4uG10FhXdBy2Bt3LiRkJAQnUTjx4/n1q1b1KlTR+u8Wq2We0OGhoZcu3aNNWvW6K1o27Zt+Pn5acVrTktLkzcJWltbc/fuXR1dxJCQEFJSUti+fTs+Pj7cvHlTxx0CpA13NjY2GBoakpSUxIABA9i3bx8BAQFcu3aNVq1aacWf14eDg4POuejoaEaOHElwcDB79+7l1q1bVKxYUTYCoaGh3L59G29vb61dzJUrV5ZDRycnJ7N//35WrVpFUFCQTh3Pnj3TCrQXFBTEoUOH9MbpbtCggRw6tmPHjrIQwpkzZ1izZg2//fabvBnT0NAQGxsbHWGC98n58+cZM2YMmzdvlsUmsnL9+nUWLVqUrdCDgkJWtAyWRgzgTbI7f/HiRTp16pRrOpAC2s+ePVvrl3XZsmWyvJFmZ/Cb1K1bl5SUFAIDA9m/fz8FCxaUY3Znx+nTpylXrpysHm1gYMCwYcPw9fXNUaDxTWVdkIYvlpaWsrE2NDRkyJAh7N27F5CGkT179iQ2NhZvb2+GDx8OwKVLl2R3kWHDhhEREYGpqSnXr1/XKv/u3bs4OjpSvnx51Go17du35+zZs1y9elXr2Wrw9fXlxIkTgBSWJCEhASEER48epUqVKgQEBHyQ+O36OHPmDNOnT8fFxYXY2Fgd6aqzZ88yatQohgwZkuMGUgUFDf8o4qiFhQXe3t65pluxYoXsB9apUyeuX79OsWLFGD9+vF7po6zkz5+fjh07MmvWLFQqFX369JHFKbIjJiZGx+eqbt26FChQQMs9423QV1aTJk14/Pix3HYbGxsmTZJUms3MzHR6EtHR0VSrVo0OHTpoabldunSJ9evX4+XlRe3atTl27BjVqlWT5auCgoK4evVqrm00MDBgzpw5nD9/HjMzM/bs2UNaWlq20lfvi19//ZVx48Zhbm5O/fr1MTU1lecYDx8+zNGjR/H396dkyZIftJ0Knw7/aJVQ45CaG7a2tpiamtK/f3+6d+8uy4KXLl2aMmXK5Jj34MGD3Lx5k/Pnz3P58mWOHj2aq5d61apVdYZeV65cQa1W51rf25R19uxZqlSpIiuiZN1xXKVKFZ1J/h07dnDx4kWaNWumNZ908uRJatWqJQ/xLl68SFRUFJ6ennh6emJubp7jHJWGly9fYmVlRXBwMMWKFUOtVhMbG/tO95kXPH/+XFY3ypcvH/ny5ZMNVvHixYmPj9cK+6KgkBv/yGAlJydz7dq1HNOo1Wp5GJaZmcnFixexsLAApJ5Hbqtu+oaZWYUu9dG+fXsyMjLYvXs3ACkpKaxdu5bBgwdnq1+XHd27dyciIkIehiUmJuLh4cGQIUPkNGfOnJHrefDggSyZpKFatWqsWLGCsLAwvLy8ZN+6adOmUatWLYYMGYJaraZnz57ky5cPd3d3+U/jypETQUFBNGvWjGnTpmFtba13lfdD0LNnT7y8vHj58iX+/v7Uq1ePokWLAtCiRQs8PDzo0aNHtgs5CgpvomWwlixZgpWVFcnJyVhYWLB+/XoA/P39sbCwIDw8nJ49ezJ+/HhAckbNOi/h4ODAxIkTCQwMxMLCgpCQEJ48eUL9+vWxs7PD0tISGxsbeRVy8+bN8pJ7dHQ0FhYW7Ny5kwULFsj+WHZ2dhgZGWFra0u7du0wNTWVJ7Ozo3Dhwuzfv5+lS5fy+eefy6q+K1aseOcHVLp0afz8/Bg7diyWlpZ89tlnVKpUSStonEqlwsbGhvbt2zN79mwdo9i0aVMGDBiAo6Mj/fv315qvmz9/Pubm5vTv3x9TU1Pat2+PnZ0dgwcPxsbGRqe3po82bdoQFhaGo6MjgwYNol69eu98n3mBvb09dnZ29OnThxMnTsgLMlWrVqVq1apYWVmxdetW5s+f/z8dgUDh3chzXUKVSiViYmJEZmbm3y7j1atXIj09PdvrZcuWFevXrxdpaWla5xMTE3XO/V3i4+OFSqXSOjd9+nTh5eUlUlNTs22fWq0WMTExObb/TWJjY4Varc4xTePGjUVqaqp8nJiYqHU9PT1drF+/XpQtW/at61VQ+Bh5r7qERkZGVKhQ4R+VUahQoRyv//LLL2RmZupMyGdVnv6n5DQ5nNMEd758+d75/jUxlLJjwIABdOzYUaveN+81X7581KhRg19++eWd6lZQ+Fj5z+gSfvHFFx+k3mXLln2QenPala/B0NAQe3v799AaBYX3g+JLqKCg8MmgGCwFBYVPBsVgKSgofDIoBktBQeGTQTFYCgoKnwyKwVJQUPhkUAyWgoLCJ4NisBQUFD4ZFIOloKDwyaAYLAUFhU8GxWApKCh8MigGS0FB4ZNBMVgKCgqfDIrBUvhoePXqFY8ePcrTOt42uml8fDzPnj0jNjaWpKSkXNNHR0fz8uVLIiMj9Wp3ZmRk5Gkk2CdPnujV88yOFy9e6OiHfgpoGazjx4/zzTffMHbsWK1EYWFhLFq0iGHDhskafm8ihGDLli1MmDCBH3/8UevavHnzcHZ2xtnZWUc5RUNoaCgDBw6ka9euuLu768Qkz8zMZPLkyfz6669689epU4d+/frJAhAZZPB//B+96IUzzgQSmMNjkIgjjnOck493sINVrNKb9jrXGcc4HHBgFrNIIvcPdXac5SyJvNY5PMABBDmLc7zkJTbY5Jjm4sWLdO/enUGDBv3ttr1PLly4wOTJk/9W3oULF+Ya/z4jIwMbGxu919zd3bW+8P7+/uzZs4ctW7Zoybdlx/Lly7l69SrTpk3T+x15+vQpo0aNyrWcv8uSJUs4fvz4W6cPDAxk3bp1edaevELLYN2/f5/69evrxFp6+PAhFStWJCgoKNtfGyEE0dHRmJiY6LzB/v7+DBs2DFdXVyZOnKg3f9GiRZkyZQoeHh6kp6fzzTffaF1fvXo1p06d4vLly3rzq1QqvL295XjvfenLKU7xLd/Smc5MYhK/kHMgu1vcYjWr5WN77OlPf510IYRgjz2f8RkrWMELXmCNNWnkLhihjxWs4AGvf30nMYlMspcjAyhEITzwyDGNlZUVy5YtIz4+/m+169/i0aNHWrqDL1++JCUlhaSkpBzVvOPi4mQjpFKpshXWSElJYefOnURFRfHs2TP5vFqt1ttjy8zM5Pbt27Lq0cuXL9m1axf379+Xex0DBgygTZs2uLi44OjoCEi9Eo2OJkhq4BoRjUWLFmFsbMzOnTv1ytCVL19e53v16NGjbGXnnjx5onWcmJgoC3g8fPiQu3fv6s0HknHMzMwkIiJCbu/z58+1elRdunTREjWOj48nJCQkRyXxjwWtEMlpaWnCxMREb5hSCwsLcePGDfk4MjJSrFy5UiuNv7+/+PLLL7XONWnSRAQHB4vnz59rnT98+LA4dOiQTj1//PGHaNWqlXx8584d0aNHD/Hdd9+JmTNn6m1b9erV5deXxWVRVBQVqeJ1+OD9Yr+oIWoIIYTYIDaI3WK3fM1W2AohhPhSfCkqi8rCUTiKvWKv2CP2iPVivU5dX4ovxRwxR+uctbAWP4mfhBBCtBatxTfiG9FStBSuwlXEiTghhBCPxCMxXUwXtsJWjBfjxWPxWJwRZ0QFUUG0F+1FD9FD/CJ+EcbCWHQX3cVEMVEIIUQv0UvYCBvRVXQV+8Q+IYQQL8VL0U10E0IIESbCREfRUbQT7cRgMVjcErfkdl2/fl107txZ7zPLa54+fSocHBxEnz59RIsWLcTevXuFEEL88MMPwtbWVnTu3FnY2tqKBQsWCCGEOHXqlOjbt68QQog1a9aIPn36iFevXgkPDw/Rpk0b4ejoKPr06aMT8vrQoUOiVKlSYvjw4WLWrFlCCCE2bNggunfvLgYMGCB69eol0tLShEqlEqVLlxaOjo5i0KBBokmTJuLFixciMDBQlC1bVgwdOlT+LvTp00dMmDBBODo6ismTJwshhNi6dav4+uuv5XqnTZsmNm7cKB4+fCi6desmJkyYIDp06CB++eUXnWcRHR0tWrZsKYQQ4vHjx6Jr167CyclJtGjRQuzbt08nfadOncTFixeFEFKI7Tp16oi4uDixZcsWMXToUDF8+HBha2sroqKihBBCTJo0Sfj5+QkhhKhSpYro37+/GDhwoDA1NRWbNm0S3bp1E61atRKbNm0SQgixc+dO4ebmJoQQYurUqaJ3795i8uTJYvz48e/2Jr8nNCGS/5HBioiIELNnz9ZKo89gOTk5iUGDBolGjRqJ4cOHy+d9fHzEnj175ONjx44JOzs78dlnn4lr164JIYTIzMwU3bp1E3fv3n1rg7VVbBWOwlHreopIEYVEIZEkksRisVg2LkIIUV1Iec+Jc6Kf6Cef3yQ2iYVioU5ddUQdcV6c1zq3UCwU44X0ZpcWpcVGsVE+v0wsE0IIMUaMEQEiQAghhLfwFrOF9Oy6i+4iVITKZZkKU5EhMuTjRCHFak8WyaK5aC6/biAayK816QNFoHAVrnLeD2mwNmzYIBYvXiyEkL6klpaWQgjJYHXt2lUIIcWdNzMzE0JIBsvJyUm4ubkJFxcXoVar5S+rJpb+yJEjxcGDB3XqatiwofyD+OrVK2FtbS1rCMydO1fs379fqFQqAYi7d+8KIYRwdXUV+/fvF0IIYWVlJZ48eaJVpkqlEpGRkcLKykokJyeLFy9eiFq1agmVSiUyMjKEqampSEpKktMnJyeL0NBQ0a5dO532ZTVYa9asEcuXLxdCCBEVFSWaN2+uk3779u3CxcVFCCFEYGCgcHJy0roeGxsrli1bJtasWSOE0DVYZ86cEUII8fXXXwsHBwe5DS1atBBCaBusevXqidjYWJ02fEz8KzHd69Spw4IFC3JNt2vXLvl1mzZt+OOPP7C0tKR3795a6Vq2bMm6devYuXMnM2bMwN/fn40bN2JjY0PNmjXful1GGPEKbTHTdNJRo8aQf64wrK/8V7zCKEvE6V70AqSh6ShGMYUp+OFHAglsYxsqVIQTzgJyf3472MERjqBGzT3uEUkkZSkrX88ggxnM4BrXyE9+Ion8x/f4b3Ds2DHGjRsHSEOiFy9eyMPT1q1bA5KMW2ZmpjzcOXXqFNevX+fKlSvky5ePkJAQqlWrJisNtW7dmmPHjtG5c+ds6w0KCiImJkYWpE1LS8PExITOnTtTqVIl+bNkampKRESE3jLGjh3L06dPqVChAgkJCYSFhWFtbU2bNm04cuQIBgYGtGzZEhMTE5KTk+nfvz+FCxemYsWKXLlyJdfnMm3aNEDSsXzy5AnPnz/HxMRETtOzZ0/mzJmDSqXC09OTYcOGAXDkyBFWr15NmTJlSElJ0RLmzYpG9dzU1FTWE6hUqZLeoeTSpUvp1q0bxYsXZ9q0aR8s3Pjb8N5jujdo0IDw8HC9enuFCxemVq1aTJ06lYoVK5KRkcGtW7cICgpiz549xMTEoFarqVq1KqNHj862jiY04Su+IoUUjJGEPI9ylNrUxhhjilGMF7wApMnrOCQ16Hzky3XuCKApTTnAAdrRTj53gANMZap8HEccpSjFU55SlrIYYkg5yvEDP1CKUgAYYKC3Xs2xIYaEE44ffhziEPnIR01qksrreRSAjWykGtX4ju8IJRQnnHK9h/eBlZUVYWFhtG/fnuTkZAwMDChVSrr37NS727dvT+PGjenXrx87d+7EzMyM+/fvI4TAwMCAsLAwrKysdPIVLlyYtLQ0ihUrRtOmTSlRooQs2KshIyMj23o1+QEiIiK4c+cOR48eBaB69eryXNPQoUPZsGEDQgjZGO/atYtmzZoxe/ZsIiMjdRad3qRp06aEhYXRqlUrEhMTKVKkiJax0rTH1tYWb29vLly4wM8//wxIk/seHh7Url2bpUuXcv36db11ZL3P3JTSHR0dcXR0JCIigs6dO3P79u131u98X2gZrKtXrxIREYFKpcLPzw8zMzPMzMyIiorijz/+ICkpiePHj5OQkECLFi24efMmHh4erFy5EpB+OYKDg4mOjsbPz4+2bdtiYGDA3r17adCgAZcuXSIgIIAffvgBkIQU1Go1gwcPxtfXl6JFi2JkZMSuXbvo2bMnRkZGWlqC33//PQkJCTkaK4D61GcEI2hPe6YznTvcYR3r2MAGAGyxZTjDscaaPeyRjYU55oQRxmEO04AG2ZY/l7l0oAPppGOPPetZTzGKyRP0BhjgjjsjGckCFjCYwQAMZCAzmMHXfA1AFFE44ogllmxnO0kk0Y52NKEJP/ETzWlOKUoRSyyhhLKf/TzjmU57jDDiBje4yEW+47scn8375Msvv6RPnz4kJiZy9uzZt14lmzFjBqtXr6Z3797s2bMHR0dHevXqRYMGDTh9+jRz5szRydOxY0fGjx9Pq1atmDhxIh06dMDJyYmOHTvy4MEDWrZsmWPPoWPHjkyaNIlWrVoxbtw4bt++zffff09wcLCWmK+NjQ3jxo3DwMCAdu2kH6xGjRqxatUqihYtyvHjx3WMz5v07duXfv368fTpU05/Sfs7AAAgAElEQVSfPp3t59nZ2ZkuXbowfvx42ehYWFgwf/58atSowcmTJ99p5KGPzMxMWQMzKiqK+vXrf7TGCsAAaQ4Ld3d3Dhw4wMWLF+WLNjY22NjYEBoaiq+vr3y+du3aDBo0iIcPH3LkyBFGjBgBSCt5WVekRowYQenSpVm5ciVRUVFYWlri4OAgd1FPnz6NEAIbGxuCg4NlpWZbW1tsbW11urvnzp3j1atX2Nra6txIjRo1dERH97GP05zGBBP60EfLCAUSyGEO053uXOEKrrgCcIlLnOQkLWlJEYrwghe0pa1OfbHE4oUXUUTRiEYMZSj5kT7YFaiAL77sZS896UkrWsn5LnOZ3ewmk0x60QtrrHnOcw5xiJvcZC5zecxjDnCAdNIZy1gCCOA4x2lFK9JIww47ClCAdrTjCldIIQUvvLjHPQYwgN/4DRdcALhx4wZTpkzh4MGD2XwE8pbMzExOnz6Nubk5ZctKw9iHDx8ihKBq1aqAtJ3BysqK58+fEx0dTf369aVndfkylStXpnz58jx8+JDIyEh5KKmPyMhIYmNj5eFQfHw8J06coGLFilhbW5MvXz7Onz+PtbU1IO2dEkJQpUoVAB48eEB0dDQtWrQgMTGRM2fOUL9+fVQqFZUrV5YN0Y0bNzAwMNBS+L5//z4hISG0bNmSO3fuyHVouHPnDhMmTJDfB7VazenTp/n8888pU6ZMtvd0+vRpGjZsKPdMhRD8/vvvpKWlYWFhwZMnTzAzM+P27duULFmS0qVLExwcTPPmzTEwMJBXaDXP+vfff6dly5Y8efKElJQUatasyZUrVwgPD6dmzZpYWlpqCf1+LLi5uckKVXkupPo+aNeunXB0dBQpKSkfuimivCifp+WnilSxRqwRo8SoHNOdO3dOdOvWTWtlS+H98/jxY9G7d2+xatWqD92UT5b3KqT6PnibzX3viwlMyNPyU0jBEEPccc8xnbW1Nf7+/nnaFoXcKVy4MEuXLqVOnTofuimfPP8Zg/UxMZOZeVp+KUoxlrG5J1T4KDAxMcl1Xkvh7VB8CRUUFD4ZFIOlkGf8/PPPfP/992+dXrNd4dKlS/JCTlYWL17Mvn37AGn7Q0pKCtHR0fJ+q+w4e/YsAwcOZODAge/kb6fw8aEMCRXyjJcvX75TBAEvLy9A8htMSEjQuT58+HDZV/TZs2cIIVCr1bn6Sj5+/Jg5c+aQnp5O165duXnzZrYbLhU+bpQelsJ7Ye/evYwaNQqVSsWECRPo0KEDnTp1YtOmTXKaCRN0Fyv++OMPevfuTXx8PDt27ODcuXM6aTScO3eOjh07YmNjw4gRI4iOjgak/WB169alfPnyGBr+c08HhQ+H0sNSyHPWrl1LUFAQXl5e5M+fn0WLFlG8eHHUajVt27alf//+GBsb68SqOnLkCO7u7nh7e1OqVCmePn0qR0fQh7m5OYGBgRgYGODt7c3WrVuZNWsWIPX2unfvjoeHh9K7+oRRDJZCnuLp6UnDhg3x8/OTd2sHBgaye/duUlJSiImJ4ffff6dTp05a+S5cuMDt27f5/fffKVq06FvV9fLlS2bNmkVERARCCNLT02WD5ePjQ+vWrT9qPzmF3FGGhAp5Srdu3Xj69CkHDhwApLhMS5YsYfv27Rw4cABTU1O9gfcsLCyoU6cO69evf+u6Vq1aRbNmzTh06BDTp0/Xil1VrVo1Onbs+M9vSOGDohgshTylTJkyHDp0iOXLl+Pj44ORkREvXrzgypUrbNiwgT/++ENvvgIFCrBr1y6uXLnCwoUL36ouIyMjwsLCOHfunOyvquHZs2c6QfEUPj0MgXmtW7dWfn0U8oTKlStjZmZGnz59OHr0KJaWlrRs2RIfHx/Kli2Ls7MzderUoXTp0oC0O9/AwAATExM+//xzevbsSWhoKOXKlaNkyZKYmppSrlw5DAwMsLKywtDQkEKFCmFhYUGTJk24ffs2ly5dwsXFhUqVKtGkSRNAithpbGz8j52FFT4Mx44d47ffftN2flZQUFD4GNE4PytDQgUFhU8GxWApKCh8MigGS0FB4ZNBy2A9e/aMI0eO6MgRpaSkcPbsWby8vHIUlbx79y579+7VK/Pl6emJp6cn27Zty7FBKpWKn3/+maioKECKx63J6+npma0v2ODBg1/rEqrV4OkJYWGvE2RkgJcX/PlnjvXz/fdw/770Ws/O62xJSZHqvHXr9bnkZOnc7ds55507FxIS4OVLcHOTzv32G2SJhf+vEBICW7ZIr7dskY7fkblz59KvXz+uXbuWa9oHDx7w22+/aZ3z8fHR2m6gj6xSXeHh4XJE26zs2LGD4ODgt2y1/l30Wbl586as06dSqRgxYgSPHj3CTfN+KHwUaBmsBQsW4OPjoyOk6unpiYeHBzNmzMhWSFWtVvPVV1/h5eWlV0j10aNHJCYmkpiYqDe/Bnd3d6ZPn07IX1+m5ORkZs+eLedNSUnRmy8oKOi1LmF6OowbB38F+gfg8GFwcYHcIm/WrQuandCNG+ecNitxcVL58+a9Prdnj2T0goJyznv8uGSsVCqpnQBlysBfUSL/NUqUAM0q2R9/wN9QWZ4/fz7GxsbZagRm5fLly1quNwBTp07N8UcvNTWVNm3ayMfPnj3TMXog7avSrCy+DY1zeS+fPn0qG0BDQ0N69+6NiYkJ9vb2b12HQt6jZbBWr16tN4D++PHj2bZtGxUrVtQ6n5CQwJkzZwDpTT5+/Hi2cbvHjBmDq6ur1i9deHg4N2/elI+vXbvGjRs3aNtWOyRx+fLlcXV1xdXVle7du7/dnZUoAQYG8PChdOzpCV9++fr68eMwZAh89RX8JTYASOk1Gxk1riLPnsHUqVL+9eul3pA+TE0hMhI07iPbt8NfIpwA7NsHAwdKxjQ3I/b8OWiELzMyYO9eGDlSautfAqCsXQsHDsDQobBu3et2798Pfn4wdizMmQMa5+DkZNBnaLZuhb59pXvM2uvavx+cncHJSXpe/zJJSUmsWbOG8ePHy0ozmzZt4vHjx4wZM4bNmzdrpY+Pj+ebb74hISGBJ0+e8OLFC63rt2/f1tpoGh0dLe/Hyur2ExUVxZw5c5g1a5Ze+XhNSPCxY8cSFxenJQKr8GH5R3NYd+/eZfny5blXki8fnTp1om3btnh6esrnDxw4IEfEVKvVTJ48WW84ktu3b9OoUSP69OnD77///vYNHDwYfv5Z6v3Ex8Nnn72+ZmIC7u4wY4b0v2Yod+SIZKBAMjgAmZnQvz9s2CD13pYsyb5OJydpKHf3LhQrBuXKvb5Wtiz88IPU65oyRWpXdty6BRcuSK/nz4czZySDsn69dE8g9RbXroXZsyXjplHVvnABZs6EUaOgYUPQSGI9eKDfUNaqJRm8AQMkA6VWS4Zt6VLp2axZA5UrZ9/WHLh+/TqrVq2S/7L6Anbo0IE6deowfvx4xo0bx+PHj/nyyy8pU6YM8+bN48ssPzAPHjyge/fudOvWjZIlSxIcHKzje1i9enVWrFghqxd7eXnJ6s7b/3ov4+PjcXBwwMHBgc6dO9OnTx+dNufPn59vv/2WpUuX4uvrK6vnKHx4/pEvoaWlJQEBAbmmO3r0KCVLliQ6OhpbW1s6dOhA1apVmTx5spxm5cqVfPnllzq9uBIlShAVFUWxYsVkhZGwrHNTOdGzJ7RtKxmnAQNe91gAqlcHf384fx5SUyEgAL7+Wn85ZcvC5cuwezfExEjDqSxqPloMGAB9+kg9NWdnOH1au05fX7h0Seo1HToEgwblfh9+fnDypDRMdHOTDObQodK1YcOgdm3pvLn56zwODtKQtnFjWL4ccpCEp3Jl2LYNrl6VhqbnzkGTJpJB3bpVup8sggvvQuHChWXREUCOlqDpUUVGRhIZGUnlypXx8fFh5MiRGBkZaeW5ffs2Tk5OeHp6agk/vEn+/PlxcHDA19eXgQMHsn37dk6cOKGVxsfHB1NTU3mHfWZmps5cWPXq1QkICODs2bM8ffqUgICAHHUQFd4f72WVsGTJkoC067lz584cO3ZMJ826devw8fHB3t6eoKAg5s2bx/nz5zE0NKRYsWIAtGvXDrVaLYcNyZXChaFRI/juO2nIk5WxY6FQIWnI1Lnz62GTPo4ckSapBw+GBQtyTlu2rDQc9fGBrl21rw0aBJUqSWW0aZNzOVlJSZHaClKvLesckGa+zchIMoKa4UvWiARFikjDQX2o1ZJBsrCQelPm5pKhKlJEMsylS0tG8bu/Jx9Ws2ZN+vXrJ/8ZG0s6kXFxcRgbG1OjRg1q1KjByJEjs/W2KFKkCCqV6q1ca5ydnfn555/5/fffqV27NuXLl9e6HhcXR6lSpeR6Fy5cSPXq1bXSLFy4kAcPHjB16lSGDBmSa7wthfeHlsF69eoVSUlJCCFITEyUV3NUKhWJiYmo1WpevHghT3w/evRIa9VPcy1r+pcvX3L7r1WysLAw/P395V+r3377jbNnzwIQEhLCrl278Pb2xtrammnTpmFpaUlUVBQJCQlkZGTg6+tLoUKFqPwuw5Nvv5WGcn8ZPZnwcOjQAfLnl+aWcuLPP6UeR716sGOHNETMiSVL4McfJSOiITMToqLAxkYyEu8iu9W1q2QwVSrYtEnqOWrYsUPqIXp7Q/PmoIn3tH+/NLQNDZUMUO3a+stOTJQMXatWkgE9eVI6HxcnDX9HjZKGhpcuvX173wJbW1uePn1KtWrVsLe3p1WrVpQsWZJChQphYGCgtThTqVIlAgICmDJlit4fu6w0btyYp0+fsmTJEoYPH65zfeDAgYSEhNCoUSPs7e1p2LAhxYsX10rz559/0r59e0qXLi1Lzyl8HGgNCT08PPDz86NJkyb06NGDoUOHMmzYME6cOMHSpUspVaoU06ZNo1mzZixfvpzExESCg4MZPFgSCh0zZozc++nRowdr166lcuXKjB07lidPnmBubs7KlSvl7v6dO3dQq9W0bt1aK0i/hYWFLE9+9+5d3NzcSE9Pp02bNlpzYNliaAgtWkiva9WS/kAakmlEIpcskXpMhQpJw6u/fvkxNwdNOBNN2iFDYPJk+OILyVi0b69bZ6FC0LSp9Lp+fekPJENRoQLkyyfNRfXqJRnPsWNfzws1bgwFC0oGTlNGuXLw6pX0evZsaY6pWzepDVnDB5ubSwbNzEx7mGpjIw1JixSRhnsg9ZY0yi116kjHpUtL5dnZSe2cPFkaej59Kq165ssntWX27Nyf+xuUKVNGZwhnbW1NgQIFyJcvHzt37sTDw4MbN25QsGBBlixZQvny5Vm0aBEjR46kUaNG9OzZkwYNGlCxYkUOHjzIxIkTMTU1xdTUVNY5fBNXV1d27txJ1yw9XI1OYLVq1Vi8eDFubm7ExMRQqlQpNmzYQIkSJeS2zp49m3nz5iGEwNHRkadZpxIUPjj/CV3C4sWLi759+4qXL1/+OwXevi1Ep07/Tll5RefOQly+rHt+5kwhNm3KkyrnzJkjatasKY4fP54n5Sso6OM/p0uY2/6ud+L5c2n1cP78f6/MvMDM7HXPMCtVq2qvTv6LzJ8/n/kf+3NR+M/ynzFY/yomJtKk+cfOGzGfZEaPfr/tUFB4Tyi+hAoKCp8MisFSUFD4ZFAMloKCwieDYrAUFBQ+GRSDpaCg8MmgGCwFBYVPBsVgKSgofDIoBktBQeGTQTFYCgoKnwyKwVJQUPhkUAyWgoLCJ4NisBQUFD4ZFIOloKDwyfCfMVgRERHcvHmTzNyigb4DSSQRRw5CER8QgeAe93JMk5yczM2bN3moUQ76QNy6dYuQkBDSNKo+2RAfH89hjcxZNjx79gw/Pz/u3buXrUblyZMn3+mer127Rmho6FunfxvOnj3L3bt33zlfYmIiB3OJRnvx4kUttan/JbQM1vfff0+LFi1o2LChVqJ9+/bRsWNHatasqaNUoiEzM5MhQ4bQsGFDxo0bp3UtMTGR/v37Y2pqirm5OZcvX9bJL4RgypQp1K9fH0tLS1mX8MGDBzRq1IjPP/+ctm3bsmfPHr31t2zZEm9vb1QqFQBRRNGTnnz2179ZzEKFKseHcY97bOa1tNR+9rOVrXrTbmEL9alPXerSmtZc5GKOZefEetYTzes49XOYQyY5G95XvGIAA3JM8/DhQ9auXZut9FpeExsbi6WlJXPnzmXdunU68m1vEh0dLYuZZkdaWhr3798nOTmZR9noKnp6enL9+vW3buepU6cIDAx86/Rvw65du/R+znMjJSWFS7mEo96/f78cWjyvmT59+t+6j7xCy2DZ2Niwa9cuHa02MzMzPDw8KF68uGwQ3sTAwICvvvqKmTNn6oSUHT9+PKamply7do2wsDAaNGigk//AgQOEhIRw8eJF5s+fz7BhwwCoWLEiFy9e5OrVq+zevZvp06eTnp6uk79o0aLMmzePggULokZNZzrTkpZc5SrHOc5VrjKPeQCkkMIrXsl5nyK1N5xwAgjgMY9JIYUv+ZKxjNWpyxdfVrGKHezgJjeZwhS60pVYYuXy1Ki5jX7F5yii5NeppLKPfYQTTiyxJJPMNrYRQ4zcu0sjjTDCeMlLOV9hChPAa8WiOOK4znUEQj5nZmbG+PHj9bbhfbBx40Z69+7Njh07+Omnn3TUac6ePcvBgwd1esVqtZp9b8TZ9/f3R6VSoVarKVq0KGFhYfTo0SPbutPT0/H29ubEiROy1FdycjI+Pj5s2LCB+xp17zc4duyYrGWQmJgoG4b4+Hh27NjBpk2btERk4+Li2L59O5s3b85WJCM2NlbuNWnuTaPa8yYmJia0a9dOPk5OTmb79u3Ztjc+Pp59+/aRkJCgZcQuXbrEYz1KSTdv3mTDhg34+vpqKXAHBATw+PFjtmzZIhv7R48ece7cOfz9/fH29iYjI4Pw8HA8PDz49ddftfJryvXz88tV2fufoGWwLC0tteSVNNStWxdTU1MMNDHO/yIsLIwhQ4YAksFq06YNRTXx0P8iNTWVX3/9FXt7e3bu3El8fDwFCxYE4KeffpKFLw8fPoy9vT3GxsZ07dqVW7duERsbS/78+SlQoAAAT548wcjIiPz58+d4U6c5TTzxTGUqhShEVarihhs/IonE/h//xy/8Iqe3wgoAH3wII4x5zOM3fmMHO1iJrkz6WtYykpFYYIEBBvSkJ81ohhdeAJhjTk96spCFtKENN7gBwAUu0JOezGY2nehECCGEEcZNbrKBDcxjHic4QTzxLGAB65B6G73oxSY24YQTC1gAwEte0g7pgx1MMKMZzY/8iC22nORkjs/nfVG9enUOHDjAiRMnSEtLkz8/mZmZdOjQgdOnT3Pt2jU6dOiglc/Q0BB3d3fCw8MBSf9y/vz55M+fn5MnT1KkSBFSUlKwtrbONtLssmXLePbsGRs3bmTZsmWA9Hl9+vQpJUuWZPTo0fj6+urkmzNnDgl/CeU+ePCAFX/Fyb9w4QKpqakUKlSInj17cuEvzcjz58+Tnp5OwYIFcXR01DFE4eHh9OzZk4oVK5KcnIylpSXh4eGsX79e/u5k5dGjRyxduhSQhn42NjY8f/6cr776ijVr1mil1Wg1lilThgcPHvBdFmWjzZs3y6OUrAQGBlKmTBmioqJo3ry5/GMxceJEJk2ahBCCYcOGZduDCwwMpFSpUkRHR9OsWTNZZFZT7oMHD7TK/bf5R3NY5cuXp2dWBRc9PHz4ECMjI5YtW0ZycjJt27aV31RLS0usrCRjERsbS+2/lF0MDAz47LPP5F+ye/fu0aRJE6ysrFi9erWO4XyT29zGFlsMeJ3OGmvUqHnGs2zzjWQkVlixgQ18wRfZprvDHTqiLUnVkY5yj0qNmslMxgsvXHDBE08AVrCC5SzHE0+WsIQNbMAKKxrRiFnMYj3r6U53ylKWdaxjNpLwwwEO8B3fsZa1+OJLBhladVtjjQ8+LGEJbrixhS05Pp/3Rf/+/Zk0aRLLly/H1NRU/iKeOXOGihUr0rt3bxwcHDAxMdEZdmjkukASRHV2dgZg6NChWFlZYWxsTL169Thw4IDeuvv06YOLiwvLli2T58VatGiBk5MTBQsWpGXLlvi8Q1RZe3t7OnfuTMGCBWnWrBm//vorAF26dMHOzo6CBQtiZWWlZQSDg4MZMWIEO3bsoHHjxhw6dAhbW1umT5/Opk2buHTpEklZJdvewNvbm+nTpzN27Fh++eUXtmx5/b6GhobSr18/Nm7cSKtWrd76PlxcXDAzM6NkyZKUKFFCq9fr5ubGiBEjmDRpEocPH6ZSpUpUr16djh070q9fP4yMjHBxcaFevXqUKFGC0qVLy8LGLi4u1K1bV2+5/yb/KERyuXLlcjVYxsbGpKSk8NNPP1GxYkWMjY3Ztm0blpaWWFpayulMTEx49uy1MYmNjZX1CGvWrMnly5d5/PgxFhYWXLt2jdKlS2dbZ2lKcxPtScmHPCSVVIpTPJtcb09pShNOOPWpL5+7yU1K87pNTZHUb1rQgpWsRI2a4xxnGtPkNIYYvlV9QxjCS15SkYrEEccd7lCFKvL1e9zDBRdMMKEUpf7RfNq/iZGREU5OTjg5OfH06VOaN29O9+7duXjxIg8fPpQVkOrVq4dKpdLqOfft25fmzZuzYMECdu3aJX8xJkyYQEZGBq1ataJ48eLZzqlqFHDKli0rD9UOHDjAypUr6dOnD2XKlMl2clszhMzIeP3D4OHhweHDh3FwcKBUqVKymO+6des4fvw43bp1o1SpUnKvEKReh5WVlax7GBoaymdZ1Mdr1qzJzZs3ad68ud52hIaGyopU5cqVIzY2Vp6SOXPmDHXr1tUqLyvZTd10796dzz//nIYNG2JiYsKdO3do2bKl1jMrU6ZMtkpBPXr0oF69ejRq1EjO36ZNG61yixUrplXuv0merxKWL1+eChUqyG++SqWicOHCOukaNmwoj53j4+NJTU2lSpUqWmkqVKhAuXLliMtJ4h1oRSvCCSeSSPncXvZigw35yU8lKvEIacL2MY/l14UpTBo5r2QBfMEX7GWvfJxKKgc4oNUr0wwDwwijMY0xxBALLPie7/H765+mjDfrzXocTDDppOODDz/wAy94oTVPBbCRjQxkIDvZSS966Vz/UGQVvC1TpowsotqzZ08MDAxwd3eX/zQ9bQ0lSpSgcePGzJs3j0aNGlGqVCkADh48yOrVqxk0aBAxMTHv1J5ff/2VGTNmMHr0aHko8yYNGjSQV+CyStTv3btX1jrU6HKCpCTt7u7OsGHDePHihVZZs2fPpnTp0nz11VdkZmZib28vK1GnpqYSERFBU42smx6ypg8NDaVRo0ayUZ8wYQKNGzemf//+qFQqateuLa9KZmZm6l1BTUlJ4datWyxevBgnJyfu3ct5lRmk900z7H716hXXr19n6dKlODk5ERkZ+bfL/bto9bB8fHw4c+YMqampuLq6Ym9vj729PRcvXmT79u1ER0ezdOlSWrZsyejRo7lw4QLTpk3j9F9y7IsXL+bChQtcv34dV1dXJk2aRM2aNZk/fz79+/fHzs4OX19fvL29AViyZAlqtZrZs2czZMgQrK2tUavVHD9+nG+//Zb8+fPj6+vLqVOnKFeuHOfOnaNevXrZ/qpoqEAF1rGOpjSlH/2489c/f/wBsMNONl5XuEJRpHk3c8y5yU3ccMMBh2zL/4ZvcMSRxjTGDju88GIIQ2iPpFeYj3wsZjHNaY4PPvwf/wfAJCbxFV/RjW6AZOi+5Vs60IFZzKIlLZnLXDrSkVGMohWt6Ec/znOelazkNKcxwUSnPRZYsJa1RBPNGc7k/q6/J7Zv3862bduoUaMG8fHx2NvbywsuX3zxBXZ2dpQrV46oqCg2btyok9/Z2ZmuXbtqDfsGDRpEp06dSE9P1zvfmhP9+vXDzc2NlStXZttDHzp0KK6urpQsWZJyWZSHhg4dytChQzExMdHSQ3R2dmbQoEEULVqUsmXL6kxXLFu2jHnz5jFkyBC2bt1KuXLlsLOzIy0tjVmzZmFomH0ve+DAgbi6utK1a1fS09OZO3eu1vVvvvmGVatW0adPH3bt2kWnTp1o164dmZmZ1KhRQ6c8Y2NjWrZsSefOnYmPj6dq1aq5PjMnJyfmzJnDd999x6FDh2jXrh329vYkJCTIgsbGxsa0aNFCLrdatWq5lvtPkHUJIyIixMmTJ+W/e/fuCSGEePz4sdb50NBQIYQQSUlJ4nIWXbzg4GCtdElJSfK1kJAQcejQIZGeni6fi4yMlOsQQoi4uDjh5+cnLl68KJ979eqVCAwMFLt37xYPHz7MVresSpUq4saNG0KtVsvnHolHYp/YJ06Kk+Kl0NYrTBSJYr/YL56IJ+KcOCefVwmVuCAuiAfigYgRMSJSROqtTy3U4rw4L3yEj4gQEVrXyovy4pl4JvyFv3gunmtdSxfp4pA4JA6IA1rXYkSMOCVOyce3xW1xUUjP4al4KvyEn4gUkeKquCpSRIp4Kp6KFqKFnP6auCYCRIBIFInivDgvhBDixYsXIiAgQHTu3Dnb55bXpKWlicePH2d7PTY2Vus9exuSk5OFSqX6W+1RqVQiOTk5xzRqtVpvmtTUVPHq1au3Pp8dr169EpmZmXqvnTt3TgwfPlzrXEpKyluX/eLFi2zL1pCUlJRrmpx4/vy53vfsn5abExpdQi2D9Skzc+ZMMWPGDJGamvqhmyLKi/J5Wn6CSBADxUAxX8zPMd2ff/4pZsyYIbZu3Zqn7VH4d7h69apo27atOHHixIduykfHf05IddGiRR+6CTI72Zmn5RekIDOZST3q5ZiuQYMGuLu752lbFP49zM3NOXXqVK6r4P/L/GcM1seEZi4rryhM4VyNlcKnh2Kocuc/40uooKCPp0+f8vz58w/dDIV/CcVgKXzU7Nu3j4sX//6+suXLl7N///5/sUUKHxLFYCnkGW/61iUkJMj78R48eCDv43kzTV05L7AAACAASURBVEhICCkpKWRkZHDixAnZL06zd+rOnTtae7xA2runcQfJyMjQ67KTmZmp5Qf44MEDrl27prMnKyoqSutYU3ZkZGSuEScU8hZlDkshz3B0dMTT05O6deuiUqmwtLQkLCyMDRs2cPnyZTIzM3n48CG7du2idOnSfPvtt9y8eZOaNWvy8uVLZs2aRVBQkBz+Zd68eWzcuJGHDx+SkpLCs2fP2L9/PwUKFMDBwYE9e/ZQqVIlbty4wcyZM7V6VqmpqQwZMoS2bdvi4uKCnZ0d1atXJ3/+/NSpUwdXV1dOnTrFypUrKVmyJI8ePeLHH3+kTp06dO7cmWrVqlGgQAGuX7/OTz/9pLPRVeH9oBgshTxD4w+4ePFiAgICsLW1xdjYGBcXF0Byv/rxxx8JCAhg6NCh+Pv7c/ToUSpWrCiXYW9vT8OGDenfvz8g7R4HyUl44cKFnDx5Ejs7uxzbER8fT/fu3RkzZgy9evUiNjaWuLg4/Pz8tLwuli1bxpYtW6hYsSKBgYFs2bJF9n/s0aMHAwcOxMfHh7179yoG6wOhDAkV8oy+ffvi4+ODEAJPT085ZJCvry/dunXDzc1NDikE4O7uTo8ePejYsSOHDh3SW+bmzZtxcHBgzpw5REREvNX81uLFi2nUqBG9evUCJHex/v37Y2lpyYABA7h27RovXrzg3LlzjB07lh49erBmzRot1x+Ng7GpqSkRERH/6Lko/H2UHpZCnqHxB9y1axd37tyRv/Tu7u7s37+f8uXL8+2338rzTV27dqVr167cuXOHTp06cevWLQoXLqw1b7RixQpCQkIoVKgQw4cPl+etKlWqxKNHj6hUqZJO5IeFCxfi6+uLh4cHo0ePBmDKlClMnjwZf39/pk2bxsGDB6lTpw4eHh6UL19e517y5VN+2z8GFIOlkKc4OzvLPnwaGjVqxKxZsyhdujSnTp2iSZMmgOQ7165dO2JiYvjss88wNDTExsaGKVOmcO/ePSZMmMBnn33GrFmzSE9PJzQ0VPaZ69GjB1OnTsXW1pazZ89SqFAhub4iRYrg5+eHk5MTqamptG/fnk2bNmFhYcHp06extrYGYNKkSQwaNIhu3bqRnp5O/vz5cXV1fX8PSyFXDJBcc5Qd0Qp5glqtJigoiCZNmmBiIjluZ2ZmEhQUBEi78RMSEqhTpw4hISHcvHmTGjVq0LRpU4yMpN/TpKQkrl69iqWlJfnz5+fUqVMULVqUmjVrkpaWJodvuXXrFnfv3qVZs2ZER0djbm7O3bt3MTY2pnz58qhUKn7//XesrKy4dOkSjx49olGjRtSr93oTblpaGseOHcPIyIjWrVtjbGzM5cuXadCgAQULFiQ5OZn79+/rjZqrkHe4ubmxbNkyxWApKCh8/GgMljIwV1BQ+GRQDJaCgsIng2KwFBQUPhm0DNazZ884cuQIO3bs0EqUkpLC2bNn8fLyyjFo/t27d9m7dy+nTp3Sufbnn3+yatUq1q9fL6uSZCUjI4OQkBC2b9+e7T6Xffv2ceXKFb3XBg8eTL9+/Xj16rV815UrV1i9ejWenp5aLhmBgYH4+0vRR5ctWya7eUycODHbezt37hwrV67kl19+0dv+N7l06ZIsoqCP7du3v7W2XGRkJD/88AMg7WE6eVJSxZkzZ062qjEg7e7u168fgwYNeqt6PnYSEhIYM2YM9vb2zJgxQ46rrvC/g5bBWrBgAT4+Powdq63F5+npiYeHBzNmzMg2jrZarearr77Cy8uLH3/8Uevar7/+iqOjo6wrl9V4aAgODmb+/Pn88MMPcsjlrBw9epTRo0ezd+9enWsAQUFBeHt7yzuXly1bRo8ePUhPT+f8+fNYWlrK0ky3bt2S43afOXNGNsKNGzfWW/bUqVMZMmQIRkZGHD16lCZNmmiJDeijVKlS8uqVPkJCQvT60ukjMTFRXlWrXLmyHLq3QYMGsgSaPgoVKoS3t/d7E93MawwNDenfvz9bt26lVatW9O3bN8/kpBQ+TrT2Ya1evZr09HR2796tlWj8+PGMHz9e5wudkJBAWFgYbdu2xdDQkOPHjxMQEICXl5dWuilTpuDr64uFhYXW+fDwcIQQmJmZ0bp1a1q3bq23l5OcnMzy5ctxcXF5K5HG+/fvM3/+fB4+fCiLFzRr1oxJkyZx7ty5bPPpU2C5cuUKmzZt4smTJ7JxcHd3Z8aMGfj5+eHr60u+fPk4dOgQFSpUYNKkSZQsWZIXL17Izr9//vknW7Zs4e7du9jY2Ojs7Tl37hznz5/H1dWVmJgYNm3aRHJyMqNHj6ZWrVpaaePi4mRFlPv378vOxAsWLCA0NJQmTZowaNCgHI3l+2LNmjWoVComT55MUFAQmzZt0vlsvAtZRUbt7OwYN24cqampFClS5N9qssJHzj+aw7p79y7Lly/PMU1sbCxJSUksW7aMpk2bMnXqVFld5MCBA/LQLCfc3NyYOXOmXrUdfQQHB9O0aVPZWIG0i/rSpUs5ettv375d51xQUBCdOnXS6sk4ODhw5swZua5Zs2YxduxY6tatS7duksBEZGQkv/32GwDjxo1jwIABbNu2jdatW2uVv2/fPmbPns3gwYNJSUnBzs6Ojh070qtXL5ycnHQiCVy+fJkbNyRFHj8/P1nBpWXLlmzatImmTZsycuTIt3pOec3o0aPZtWsXAQEBjB07lnnz5umkCQgIwMLCQudvxIgResuMiYmhe/fumJmZsWrVKsVY/Y/xj3a6W1paEhAQkGOaFy9ekJCQQL9+/XBwcGD8+PHs3r2bESNGMHny5FzrOHPmDOnp6bRv317H5SKnOrM60ILkJlKgQAEtiaa/W1aFChV4+fKlrF/Xo8f/s3fe8TXd/x9/ZiH2nrGFICoItYldM1ohVtBfUQ1ftELt0dpVqjYhsdVIzFhJECNWdkJiBQkie4ism8/vj9N75Lo3wddo43uefdxH7/mczzrnnvM+78/7xPtlTePGjWncuDHLli3T0FcESRtv69at2Nra0r59e7l8x44dFC5cmKNHj2JsbMzu3bupVq0a/v7+gLSk8/T0pGzZsm+cZ4kSJVizZg33798nICCAxMRESpR4fw3G96FAgQI4OTlhbm7O5s2bqVmzplad3r17y0b+bShfvjzr16/H29sbBwcHevbsqRit/yE++lvCihUrYmBgQPfu3dHX16dbt246g/K5sXbtWoKCgujRowebN29mz549b1xWmJmZcebMGQ3vxMvLiyJFimh4XW+DmZmZrBys5tSpU5iamsopbXPeMMbGxlpGcf/+/fTq1YstW7bQtWtXubxUqVI8e/aM1NRUQFrulSxZkho1alCjRg1mzZoli1vmxZMnTxg/fjw9evRgxYoVFCtWLM+XI5+SXbt2YWVlxaFDh2QDn5N39bAMDAyoUqUK33zzDSYmJgQEBHzsQ1D4F6FhsF6+fEliYiJCCBISEuR4UWZmJgkJCahUKpKTk+Ub8smTJ+zYsUNur96Xs37RokXp3r07+/fvJyMjA1dXV/mJeunSJTkgnJ2dTUJCAunp6aSmpso33LZt2zhx4gR79+5l2LBh9O/fn0GDBuV5UG3btqV+/fpMnjyZZ8+ecfXqVebMmcO0adPe+QT17dsXAwMD5syZQ1xcHB4eHixdulSjL1dXV+Li4vDx8eHFixda8aM7d+7Qq1cvNm3axOPHj+W4U+/evZk7dy49e/bk+fPn2NraEhgYiLm5OT169KBJkybyP2fJi7CwMKpVq4alpSXe3t65qiF/as6ePcvFixc5deoUVatWZeXKlVp1evfujZ+fn9bH0dFRq+61a9c4ePAgly9f5vfffyc2NjZX1WSFzxMNg7Vx40ZsbGxo2rQp1tbW7Nkjqb94eHhgbW1N6dKlcXBwYP78+YD09srb21tu//3337N+/XoSEhKwtraWYy2Ojo64uLjQo0cPmjZtKsvb37t3jzt37gBSrMva2prQ0FBcXFxko1S4cGFKlixJyZIlqVu3LvXr19f4h625cfLkSQwMDOjXrx/Tpk1j1KhR/PTTT4D0pk0tItmoUSNZkVj9j2BzYmRkhJeXF1FRUXTr1o1FixYxa9YsjT8V6NChA8OHD2fZsmWyAS9btix16tQBYObMmVhZWTF48GB+/fVXDA0NqV27NhUqVKBHjx4sWbKEuXPnUrJkSf744w/mzJlDt27d5JcMRYsWxdzcHIDq1avLS1QhBHp6erRv357KlSvTqVMnzp49yw8//PBW5+hjc/fuXXbt2oWBgQErV64kKysrVwn1t6FChQr4+fmxc+dOypUrh6enpyLc8D/IZ6FLWKJECTFo0CCRmpr65sofkKlTpwpnZ+dPOqYQkpho48aN8xSufPnypRg0aJAoXrz4J5yZgsKH57PTJYyKikII8ck9i2rVqmlIl38qJkyYwIwZM/L0MAoVKoSTk5PihSh8Nnw2BqtgwYL/yLj29vb/yLhbt259q3r/hqWhgsKHQvm3hAoKCvkGxWApKCjkGxSDpaCgkG9QDJaCgkK+QTFYCgoK+QbFYCkoKOQbFIOloKCQb1AMloKCQr5BMVgKCgr5BsVgKSgo5BsUg6WgoJBvUAyWgoJCvkExWAoKCvkGLYOVmprKo0ePtCpmZWXx8OHDNyZgi42NJTo6Wqs8MzMTPz8/OamfLiIjI/H399dIpZuamkp4eLjGR5eQxObNm9mwYQMZGRlyWQYZBBBAOOF5zjk3bnMbH3LPI/+c59zkJi94tzzxH4IssviLv/Ks8+DBAzZs2ICbm9snmpVu7ty5g5+fX54CIJ+KAwcOaFwjn4K0tDQOHToEwK1bt7hx48ZbtcvKytJSsPpfR8NgjRw5EktLSxo1aqRRadWqVdSvX5+GDRvmmn5XpVJRt25dLC0t+eGHHzT2BQYGYmpqysyZM5k9e7ZGllI1M2fOZNiwYfz+++9YWFjIijP+/v5MmjRJ/tSuXZuIiAit9nPnzsXMzAwDAwMAznCGalRjBjPoSU/a0Y6n6NZUVOOPPz/xk7wdQQT30D7edNKxw47GNGY5y6lCFdayVqve22KPPaG80jnsRjeyyVtvT4WKi+StN1isWDGMjY35888//+u5vQ9RUVE0a9aMuXPnsm7dOg0Bjn+KS5cuySmqPxWZmZlcvnwZkLQF3kYpCiSDpb4PFF4hZxzNyMgQ6enpWhkqMzIyhBBCWFhYiFu3bsnlWVlZIjk5WaPe0aNHxYABAzTat27dWri6umplEUxLSxMvX74UQgjx4sULufz48eOib9++WvUvXrwo2rRpozMjYfXq1eXvCSJBlBVlhbfwFkIIkS2yxTQxTQwSg4QQQgSLYHFP3JPrHxFHhBBCrBArRGvRWuwRe0SICBH3xD0RLIK1xlomlomeoqd4KaS5PxFPRAVRQfgKXyGEEK7CVYSLcLFZbBZPxVONtrEiVmwX28UT8UQIIcRD8VA0E83EUrFU7BV7RYAIEBVEBbFL7BJuwk06bnFRrBarxTlxTqiESgghRJbIEifECSGEEKkiVbgIF7FWrBV3xB2N8UJCQsRXX32l85x9bH755RexcOFCefv17KheXl7i+PHjQqVS5dqHp6enOHPmjNw2JSVFnD17VgQHBwtHR0fx/Plzne1CQ0PFhg0bxMGDBzWy0J48eVJkZGSIS5cuiWfPnsnlAQEB4s6dOyI1NVW4uLiItWvXirCwMHn//fv3hb+/v3B3dxd79uyRr1tdXLhwQZw8eVKec3p6ujh16pQQQoiNGzeKOXPmCCGESE1NFQcOHJDvL39/f7F//36Rnp4uhBAiMzNTuLlJ18CDBw+En5+f8PDweOP4nyPqjKMaHpaRkZFOi5Zb+fXr1zVUYHTVS0xMJDg4mEePHjFixAiOHTsmq/UuXbqUxYsXA5rKM4mJiToVjR0dHXNVU8nJec5TnvJ8iSRQoIceoxiFCy5kk40rrrjjLtefwASd/XjiySEOaZUf5CBDGEIhpOR4lahEd7rjggsAoxnNT/yEAQZYY81ZzgKwhz18y7eoUPEt33KUt3vSnuY0JpjggQdf8zUAaaThgAMAd7jDIx5RjnI44MBW3i6538emevXqHD9+HA8PD9LT0+XMp9nZ2XTu3Jnz588THBxM586ddba3srLi1KlTeHh40K5dO0Dy2oYMGcLKlSvJzMykVatWOpd4Z86coXTp0jx58oQWLVrICkrTpk0jNTUVPz8/1qxZI9cfN24cGRkZ3L17l0ePHlGuXDmmTp0qi2GcP38eGxsbPD09uX//Pv369dM5527dunH06FEuXrxIq1atEEKQnJzMjBkzNOrFxsbSp08fDA0NMTIyYtCgQezZs4eoqCjatGlDWloaaWlpODg4yOMPHDgQd3d3Hjx4QN++fd/lp/hseK+MoxYWFuzduzfPOlFRUSQnJ/P06VOmTJnC5MmTEULIGoXiNemn8PBwFixYoOU2Jycn4+bm9lbLm6c8xRJLjbJ61KMABYglNtd2rWnNda5jiy0Al7n81v03oxmBBAKQTTazmIUFFphgwl720oUubGITi1hEKUpRkYpsYhOHOEQVqtCDHnzBFwAUpSiDGIQB0vJ2NrO5xjVqUYvd7CaFFPR4lfb4C76gOtW5wAXa0pYDHOBbvn3jefrYDB48mIIFC7Js2TKCgoKwt7dn+vTpXLhwgUqVKvHNN98AcPHiRXx8fGjatKncNjAwkEKFCskPtN69e+Pr60uJEiUQQrBhwwYMDAy4evUqV65ckRWh1djb2xMcHExaWhrly5fHy8uLjh07yvttbW1p1aoVCxYs4O7du2RlZdGgQQNASnvt5eVFu3bt2L9/v/yQbNCgAb/88gsgyZelpaVpZHQNCwsjKytLFhcOCQnh6tWrmJqaaswtPDycfv36sXz5clq1akV4eDjPnz+XxV1CQkI4fvw43bt312hXv359fv31VwB27tzJy5cv31pc+HPhvd4SFipU6I2S6GoR0BkzZtCoUSO+//57OQBZpkwZDZHQiIgI+vXrx9atW2XFGTX79u2jd+/essJNXlSlKl54aZT54osKFWWRxhO8MpRZvFtMQ1f/XnhRjWrydm1qA1CXuoQQggoVfvhxmMM44cQ5ztGc5m8cK4MMLLHECy+KUhQDDIhAM4Z3iUv0ohePeUw5yumMu/0TGBoaMnDgQE6ePImvry+bN28mODiY69evExERgZOTE05OTtSvX1/rZU5AQAB169aVt83MzGQNQlNTUzlWWbZsWZ4/f6419tdff82OHTswMjKiWLFiWrHX0qVL88UXX3D+/HmcnZ0ZNWoUAJcvX6ZXr16yl3X//n2NOajRpf0YEBBAvXr15O169erp1E308fHByMgICwsLAG7cuEFCQoJ8PooVK6bzOs85fvHixf812pOfkvfysFJSUnj48CENGzbMtU7p0qUxNzfnzp07NGnShNu3b8s/VGRkJEIITExMePLkCb1792bNmjW0atVKqx9HR0eduna6sMJKfos2kIG84AVrWMNwhqOHHg1pyHnOAxBEkByML0tZEkh4Y/922OGEE73pTUUq4osv5zjHIhbJdbzwoic98cCDTnTCAAO6053e9KYtkly9OrD++rjq7TKU4SpXaUADpjGNWGJ5wAOt+bjgwgQmMIhB7GLXW52jT0FkZCRVqlQBJMOivgn79+/PiRMnWLJkiVxXHSZQ07VrV1asWCGXnz9/np9++omXL1++cdy0tDQCAwM5dOgQ2dnZLF26VGe9kSNH4uTkxJUrV7h27RoALi4ujB8/HltbW3bv3v1Ox9u5c2cWLFiASqVCX1+fc+fOyVJ5Ofn666+pVasWvXv35vDhw3Tv3p158+axaNEi9PX15fOhFthVeIWGwVq0aBH79u0jJSUFCwsLxo4dy7hx4zh69CizZ88mLCyM/v3706lTJ1mRefLkyVy5cgWAPn36EBwcTFxcHBYWFjg5OWFhYcH69euxsbGhTp06FC1alI0bNwKSEVKpVMyfP5/Zs2fz+PFjJkyQ4kkmJiYcO3YMkFzkpKQknbqBujDGmCMcYRSj+JVfiSGGTnRiJZLB60xnVrGKbnSjGMUoT3kA6lCHEpSgE50Yzehc+/+O74ggAnPMqUMdIolkC1swxfTvk2rIDnawmtUArGMdADOYwa/8ykpWokJFQxqykIUMYQjzmY9A4IEHoxmNDTbUoAYb2ch0ptOPfsQTT0O0Hw422DCOcexgB2Uo81bn6FOwa9cuduzYQY0aNYiLi6NHjx7yw61bt250796d8uXL8/jxYzZv3qyxdCpfvjwDBw6kS5cu6OnpYW1tTaVKlTQ8ntwoVKgQnTp1onv37iQkJFC5cmWd9Xr06MGYMWOwsrKiRIkSANjY2PD999+za9cuypR5t3NZqlQpRowYQZcuXTAwMKBbt25Ur16d2FjtMMSIESMoWLAgvXr14siRI/z444/07NmTMmXKEBUVxezZs2nWrNk7jf+/wifRJczOzhZJSUkfrf9y5cqJ9evXy29Y1CSIBJEu0nW2SRSJ7zWmSqhEjIjRKq8gKgghhEgSuo83SSSJZJGsc19uJIgEje3H4rHoJrppzOX18e7fvy/mzp37j70lVFD4UHxyXUI9PT2KFSv20frfuXMn2dnZskutpgQlcm1TnDfLwOeFPvp5ejTF0H28uZXnRc7jeMpThjKU8YzXmMvr/RYuXJiWLVvSp0+fdx5PQeHfyGejS9itW7d/egoyz3j2UfuvRCU5BpcXFSpUoEePHh91LgoKnxLl3xIqKCjkGxSDpaCgkG9QDJaCgkK+QTFYCgoK+QbFYCkoKOQbFIOloKCQb1AMloKCQr5BMVgKCgr5BsVgKSgo5BsUg6WgoJBvUAyWgoJCvkExWAoKCvkGxWApKCjkGxSDpfCPkptsHMDdu3dRqVTcuXPno4z97NkzOatnXvP4VDx//pyEhAQiIyN58eKV1mVUVBSJiYlERETkmoU0Ozub8PDwTzTTfw4Ng+Xu7s706dMZN26cRqXAwEB+/fVXRo0axdOnurX9hBBs3bqVCRMmsHattkbfxo0bsba2ZtCgQTx4oJ3mNyAggJEjR8qfI0eOAJKm2+bNm7G3t2fbtm25HoipqSm2trZSCt3MTBg5Eg7lULxJSoJRo+DEiVz7AKQ6wcHS9+ZvzrkuExcnjXnmzKuyyEipzMsrt1YSffvCs2fSHLt0kcoOHYIcKYQ/CO7uMH269H36dGn7HZk7dy5NmjTh4sW8NREBTp8+TY0aNTh37pxcps5AqhbU7d+/PyCJrTo7O2u0Hzt2LAkJCXz33XfvPM+3YdasWXK23NyUez4l27dv5+zZs6xYsQJ/f3+53MnJCQ8PD5YvX05gYKDOtklJSYwYMeJTTfUfQ8NgPXz4kAYNGmjlso6IiKBSpUp4eXnlmvheCEFkZCTFixfXuEAB5s+fz5EjR2QhVV1KHxEREbx8+VIWTP3yS0miKyMjg+joaAoUKJCnqGRmZiZ79+6V+s7KAldXWL78VYW//pKMSVBQnieEuXOhVi3p+2s3UJ6kpMDJk5pjbt8OZ8/C3bt5t42LA5UKhICYGKnMykoydh+SFi3A3l76npQE/4US8/z582natOlbqSenpqZSsmRJWSoLYNu2bRQpUkRu7/630bx16xbHjx/X8Hr27NlDdHQ058/rzv2VlpZGcnIyiYmJGg/BBw8eaKgxxajPKdL1lJSUlOe8k5OTCQwMfKPgamJiIsnJyfJ2VlYW8fHxZGZm6nwog3ROcnpP6jYA48ePp169eixcuJDWrVvLdf7zn/9Qp04dli5dKt8X2dnZxMXFoVKpCAwMpESJErK4y8uXL0lJSSE5OZknT57keQz5DY0Eft9++y0ZGRmMHz9eo9JXX30FoKHjBpKBc3FxYdKkSejr6zN79myOHTtGWFiYXEelUvH777/j4+ODvr4+NWvWlPedOnUKIYScZK5QoUIULlxYQy2lSJEizJgxg127duHp6fn2R1a4MJiago8PNG0Ku3fDoEGv9q9bJ3kxKhW0agULF4KeHvz2G4wfD2ZmMGGC5IU8eABjx0JGBlSuDDNmgLm59pgVKoCRETx8CNWrS0Yzp37cokXg4QHZ2ZIn9ZpWnQaXLkmGbtIkePwYli0DX19o3x4cHKBUKRgzBsqVgwsXoEoVWLAA6taFP/6QvLvr16X5zJ4N7dpJ7c+dgzlzNMeaOFEy5Pr6MHAgjP47n/3PP0tt0tLAzg7eQhPyddTCI8nJyURFRVGqVCkNwYnmzZsTHh7OgQMH8Pf3Z968edjY2JCVlcW2bdsoWbIkoaGh/Pbbb1o5zl1cXFi7di0lSpQgKSmJ5s2bExUVhZ6eHqGhoXh6elK0aFFatGjBvXv30NPT49y5cxw8eFDWFXidiIgIxo0bR82aNQkJCWHUqFEMHTpUq97kyZO5ffs2GRkZtGzZkoULFxIaGoqNjQ0mJiaUKlWKhIQETp06pdHu5s2b/Pbbbxw+fBiQdA0ePHjAkiVL6Nu3L/Xr1+fOnTt06NCBadOmkZ2djbW1NWZmZoSFhdG5c2emTJlCREQEnTp1wsTEhFq1arFixQq6du2Kj48Pu3btYufOnbIEmYWFhYbgR37mvTKOZmRkEBcXl2ediIgIDAwMGDJkCCYmJkRFRbFnzx6qVq1KSkqK/CQsUKAA0dHRODg48PjxY1auXKmlNffOjBwJTk5QrBiULg05JMUYOhR++EH6PmYMeHtLhisyUrpBAdRxjYoV4fhx6ea/cQNWrIDclqfDh0ueVZcukqHMoVuHvb1kpISAb76RDNJrcmYySUkQHS19X7gQ2raF1aslY+PoCFOmQESEZGTOn5c8uRkz4MABqd2VK3D6tOSxde8OISGSFxgVpT3WggVQooRkvDt0gMGDpXZXr4L6IaE+J/8FNjY27N+/nwcPHjBy5EhWrFihVee7775DT0+PDRs2bDgTUQAAIABJREFUyGXdu3cnPj6eU6dOsXPnTp2iDNnZ2Rw/flz25jw9PWnTpg0TJ07E3d09V8HT3DAxMeHo0aO8ePGCe/fuMXHiRC2Ddf/+ffz8/OQHaLNmzZg4cSIgKQX5+vpSsGBBevbsSVhYmMYDuF27dowZM4bo6GjKlSuHs7OzHOo4ffo0GRkZRERE8M033zB16lT09fU5deoU6enpREREYGNjw08//QRIDsPNmzcpUaKE7KWpEUJw8uRJhBCYmZlpKPLkZ97LYJmamrJgwYI31ouPj2fr1q00bNiQZcuWsXPnTqZPny4LaQJ06dKFLn/Hb86dO8fSpUvf32BZWUneSKFCkvHKuf6/fRvWr4fnz6VPtWqSwdKFnp7kpQQEQIECkCO+oIW1tWRcHj+WPJJ9+17t8/GRjE1cnLTf3T13g5UTNzdYuVKax7BhUr9TprwaT18funaVvMC/FY756iswNoaqVaFSJQgNzb3/s2eleb54AU+fSt5d165S++7dJc908OA3zzMXhg4dyqBBg3j58iVz587VabBex9/fnxkzZlCyZEkKFSpEaC7zVy+RChcuTOXKleWlVPXq1XNtkxcpKSkMHjwYY2NjKlWqhI+Pj1ads2fPakjRtWzZEk9PT8zNzWnWrBkFCxYEoHbt2loGC2DIkCHs2bOH7t27o6+vT7169RBCMGTIEDIzM6lUqRJRUVE8evSIqlWrMmTIELKysqhcuTJPnz6Vl3nm5uay2s/rtG0rScmptRTi4+PfWQXo38hHN7mVKlWiaNGiVK1aFZAupDdJNand4vdGT0+6cffulf6fk59+kjyLEyegR4+84zk7d0pLzBMnpOVWXnpxhQpBs2aSd/L3zQRIy8CffpK8pBMnoHXrt48hlS4N6thhTIzk8alRS0i9fCkZ078FRskpLRUXB7ldrMnJkge3c6fkRdapI3lT+vrSPFevlgz13x7Ef0OFChWoVq0aPXv2xNBQ9zPS2NiY9BznY+3atUycOJFdu3bRvXt3Ld1CNXp6ejq3c5arb3SQlmR5sW/fPlq0aMFff/3F5MmTNeJNapo3b64R/A4KCsLSUlICfxsvxs7Ojp07d+Lk5MTIv+OU58+fp2DBghw4cIDly5eTlJSEEAJPT0+KFCnCgQMHWLJkiVwO0qokNz4Hb0oXGldPQEAAYWFhZGZm4urqipmZGWZmZjx+/JibN2+SmJiIu7s78fHxtGrVitu3b7Nx40ZZ4PTs2bN4e3sTGRmJq6sr7du3p3Tp0owaNYqZM2cycOBAVq9ezaJFkuDo7t27UalUDB8+nCNHjmBsbEx2djbr1q1j2LBh8rzc3Ny4efMmDx8+xNXVlc6dO7+9As/MmfCf/7y6kdUIIXk8vr5w8CAMGJB7H0ZGEBYGN29KN/CbLoYVK7SNkb6+FAPz85M8ulOnIA8BWg2++QamTpWWsAsWSG8y1WzdKsXL9u2TDK+aEyekZendu9KSOOdyOCeGhpLR8vWV5nbjhlR+5w7cuiXF6mrVevOLgzewffv2PPdbWFjg5+fHzz//jLW1NRYWFvz+++/cvHnz3WKXOujfvz9jxozBwsKCCxcuUL9+/VzrNm7cmFWrVlG0aFHc3d0pXlxbWalJkyZkZGTwww8/kJmZSZkyZahduzbB6rfLb6B69eoUK1aM7du3c/v2bQAaNGjAhQsXWLlyJefOnaNUqVIANGzYEE9PT1auXImnp6dc/r+KhsF6/PgxQUFBTJ06FT8/P0qWLImZmRlxcXH4+flhZ2dHdHQ09+7do1WrVhQtWhTzHMHnkJAQDA0N6datG35+fjRr1ozSpUuzcuVK1q5dy/Hjx1m3bh2NGzcGoEqVKvLTokSJEri6umJkZMSPP/4ou7QgPcGKFy9OmzZt8PPzo3Xr1nkbLCMjyZsBaVmjfivZrp3kdYEU29q+Xdrn6PjKwNjaSh6MENLNrC7LzJQC9/b20KSJ9pglSoD6z0GKFpU+IC2pKlSQvu/ZA7t2ScbD2flVfOvbb6F4cclD+v57qaxRo1ee1KxZUrD8yBEpcJ8zlmNvD0ePSsH4HEtsxo6Fa9ckz0od+DU1hV69pO+9eknbxsbSXPbvl7Z37pQMVPHikkF3c5OOd/783M93LrRt21ancVi1ahV1/l4K7927FwAjIyMCAwPx9fWlcuXKtGzZktatW/P06VPGjRun861b586dadGihbyt7gukuJn62vrpp5/o2rUrMTExTJ48WRY2dXBwoMLfv426raWlJceOHcPPz49hw4bl+vdZp06dIiAgAAMDA1kctmbNmhrL3YkTJ+ZqYBwdHYmPj5ev4/Lly3P16lUuX77MgAEDiIuLo2LFihQqVAhvb2+uXLmCjY0NMTExlCtXDoD169fL/RUrVozNmzcD0KtXLw1vdePGjbkuHfMjn0RI9WPToUMH0a9fP/HixYv37ywzUwgnJyEGDnz/vj4mX30lhI+PdvnMmUJs2fJRhvz555+FlZWVuH79+kfpX0FBF59cSPVj8/rffr0XGRlSzOi1P+P41zFw4CvvLSft20txr4/A4sWLP0q/Cgpvw2djsD4ohQtLca9/O7n9Yem/SFRWQeFD8nm+SlBQUPgsUQyWgoJCvkExWAoKCvkGxWApKCjkGxSDpaCgkG9QDJaCgkK+QTFYCgoK+QbFYCkoKOQbFIOloKCQb1AMloKCQr5BMVgKCgr5BsVgKSgo5BsUg6WgoJBv0DJYqampPHr0SKtiVlYWDx8+JDMzM88OY2NjiVaLJyAlww8PD9f4JCQk6GyrliyKzZHeNzU1Vat9uo7Uwps3b2bDhg0a8lMZGRkEBARoCUwGBwfLum9ubm5yAv/X5c1ykpaWhq+vLxEREXkev5rw8HAuX76c635vb++3TgMdGxsrq6/4+PjIWSpdXV1zFdYESfpsw4YNcmK3T82jR49wdnbW+E0OHDggX0NOTk54enqyfPlygt4gv5aenq4hqQVSquG4uDgmTZr04ScP/P777/K1M2HChI8yxocmOTlZ4/6YP38+z549e6u2ISEhGiIg/0Y0DNbIkSOxtLSkUaNGGpVWrVpF/fr1adiwYa4ZGFUqFXXr1sXS0pIf1Go0SDe6Wmtw0qRJtGzZUiMzpJoXL17QqlUrpk+fjrm5uWw8/P39NdrXrl1bp9GYO3cuZmZmGPydCvnMmTNUq1aNGTNm0LNnT9q1ayfn9T5//jynT58GJOmynOW62L9/P1WqVOHXX3+lffv29OrVK1ejq+b58+eyWKguDh48yNWrV/PsQ83jx4/lC+nevXvy8Xt7e+s03mr09fUxMzNj7ty5bzXOh8bHx4f/+7//05DUmjJlimxkmzZtSq1atWjXrp2c+TM33NzcmPOaPJmNjQ2FCxemd+/eH37ywMWLF+WH2dGjRz/KGB+aOXPm4ObmJm+7u7trGfrcKF68OLVr1/5YU/sgaBiszZs34+fnp1XJ3t6eO3fuYGpqqlGuUqlISUkBwMDAgODgYP7880+NOsbGxri6uuLq6sq+ffvQ19dn0N/6gOnp6aT9LR+1e/duzM3NOXbsGJcuXcLBwQGVSkWrVq3k9g4ODrRq1UrnSS1QoAAdO3bEwMCAxMREhgwZwuHDhzl27BjBwcG0adOGyZMn53ky+vTpo1UWGRnJd999h7e3NwcPHuTOnTtUqlRJNgL+/v7cvXuXvXv3aiQRrFKlCk2bNgUkJZYjR46watUqvHSoQMfExGjcEF5eXri5uekUXmjYsCG1/hZ67dKliyxKe+HCBf78808uXbokpwY2MDCgY8eOeYoVfGx69+7N2rVr5etEjRACFxcXfvzxR9zd3WUjtnv3bg2hiAMHDnD58mW2bNmCu7s733//Pd7e3gQHB3P8+HH+7//+j9jYWJ3CrmoNwilTpvDtt99y584djh8/jp2dHa6urnK9mTNnyt9v3LihsU8XDx8+ZObMmcydO1fnw1OlUvHHH39gY2PDqFGjePToEbGxsbL2AUiaiurjnDZtGufOnWP48OFs2rRJ5ypm165dnDp1ivHjx+Ps7MzNmzf57rvvsLOz49ChQ6hUKh48eIC7uzsbNmzg+++/11ipqM+tq6srCQkJTJ06lQEDBrBmzRq5XmpqqvzwDgsLY+rUqVhbW8saDIcPH+b69eta5y02NpYpU6YwYMAA1q1bpyU59iHRMFhGRkY6K+VWfv36dbp27frGempcXFzo0KGDnOd66dKlcgbL69evy7pztWrVIiMjg8jISI32jo6O/N9biHmeP3+e8uXLyxJQenp6jBo1ChcXl1zVV0C323/ixAmaNWsmG2sDAwPs7Ow4ePAgIF0E/fv3Jyoqir179/Ltt98C0oWvll4fNWoUYWFh1K5dm5CQEI3+79+/T79+/ahQoQIqlQorKysuXrxIQECAxrlV4+LigoeHByA9TePj4xFCcPr0aUxMTDh27JhO4c9/ilKlSmFnZ8eqVau09rVt25YtW7ZgaWnJ6L/FW8uXL89vv/0GSEZt9uzZmJqaMmDAAFq2bMm8efOwsLBAX1+fKVOmsHz5ctzd3XUameDgYH7++WcGDBhAhw4d+Oqrr7h27RqzZ89mwYIFslzWrl275DZ3797N0/ONioqif//+fP3113Tu3BkbGxutOocOHSI0NBRHR0d+/vlnChUqRFJSksZDydvbW16tbN++ncOHDzNv3jxOnTol/745uXDhAvPmzWP48OH07duXAgUKMHPmTBYuXMj+/fvx8PDAxMSEli1bYmtry7x58yhZsqTc/pdffsHd3Z3evXujUqmwsbFh48aNGBoayg/fyMhI+aE7ceJE+vTpw86dO2X5vWvXrmmEMdTnLTs7m8GDB7Nx40ZUKhW//PJLrufvfXmvoLuFhYXO5V1uvG5w7O3tZSMRHx+PiYmJvK9atWoaljo5ORk3NzcGDhz4xnGePn0qyy6pqVevHgUKFNB66vw3fTVt2pRnz57JnkzHjh2ZOHEiGzZs4PLly7x8+VKjfmRkJNWqVaNz586MHTtWLr9x4wbDhw/H2dmZFi1a4OnpSbVq1ejfvz/9+vXD2NiYgICAN85RT0+POXPmULZsWczMzLh27VqeS8VPzcSJE9mxY4fGuVfr5a1Zs4a9e/fi7+9PUlISnTt3Jjg4mNjYWE6fPo2FhQXlypWjZMmSFClSRBZmqF69Oj4+PixevJgnT55w/PhxnWP36tWLli1bMnToUKKjo5k2bRqmpqZ06tQp1xBAXvz111+Ymppy/fp1QkJC5NhmTipUqMCVK1f466+/qFChAuXLl39jv9OnT6d27doMGDAg13kNHTqUL7/8klKlSlG9enWuXLnC4sWLiY2N5dixYxgZGVGkSBFKlixJxYoV5fDIpEmTSE9Px9HREUNDQ8qUKUNCQgK//fYb3t7enDx5UmusihUrsm3bNq5evUrz5s3znHu5cuWIiYlh2bJl3LhxgxMnTrzxeP9b3stgqS+ctyE8PJz79+/TuXNnuaxMmTKU/Vt+qmzZshrB8fv378vqICDpxfXu3ZsiRYq8cayqVatqLb18fX1RqVTyeG+Lrr4uXryIiYmJrH1XJ4cYqomJiVaQf/fu3Vy/fp0WLVpoxJM8PT2pVauWvMS7fv06jx8/xsnJCScnJ8zNzd/K8KSmptK8eXO8vb0pVqwYKpWKKF0Kz/8QRYoUwd7eXkMuPTIykgkTJtCjRw9WrFhBkSJFSEpKkr1hZ2dnNm7cyDi1EtFrrFixguDgYCZNmsTo0aNzfRCpf29DQ0NKlSpF4cKFASlUoUtzMCkpKc9jiYuLo3Tp0tSoUYMaNWqwePFiKleurFGnffv2uLi48PTpU9q0acOVK1cwMjLSWOq9Po7aqBUuXDjXFynVqlWTv8+bN48nT57g4ODA0KFD81RgL1u2LPfv3ycrKwuQViBr165l8ODBLFy4UOcSbuvWrdja2rJ7927atGkDSCso9dI7MzNTDuecOXOGzZs3M2zYMH755ZdPtyR8V1JSUt5ai23btm2MGDFCQ+AyMjJSjgG0b99ejr/4+flRtmxZKlWqJNd92+UggJWVFVlZWfz111+AFNBfs2YNw4cP1xLefBN9+/YlLCxMdtMTEhLYuHEjdnZ2cp0LFy7I4zx69AgzMzONPqpVq8by5csJDAzE2dlZvnAcHByoVasWdnZ2qFQq+vfvj76+PkuWLJE/uuTZX8fLy4sWLVrg4OBAy5Ytdb7l/af5/vvvOXr0qPyyIiwsjOrVq2NpacmVK1c0ZLxGjhzJ5s2buXfvHu3btwckFeW7d+/KN0xQUBDt27enYsWK7Nmz573m1qhRI7y9vYmPj9dYHupi2LBh+Pr6YmFhQY8ePWjYsKGWhFZ4eDiVK1dm9uzZ2NjYEBwcjImJCbGxscTExPDo0SOOHDnyXnMOCgqiU6dOlClThv3798vltWvX5tatW7L3DzBr1iwsLCywtbUlMzOToKAgGjdujLm5OXv37tUZMwsLC6Nbt25s3LiRpKQkXrx4IStcZ2VlsW3bNtmwBgUF0aRJExo2bChrjX4sNAzWokWLaN68OSkpKVhYWMi6Z0ePHsXCwoLQ0FD69++Pvb29PNHvvvtObt+nTx/+85//cObMGVkYE6Q17vbt22WVWzWOjo7yK/cBAwaQlpZG06ZN6dGjB2vXrpWNS0hICElJSbRs2fKtDsrY2JgjR46wePFivvjiC0xNTUlPT2f58uXvfILKlCmDq6sr48aNo1mzZtStW5fKlSszY8YMuU5mZiYdO3bEysqK2bNnaxlFS0tLhgwZQr9+/Rg8eLCG+vH8+fMxNzdn8ODB1K5dGysrK7p3787w4cPp2LGjlremi3bt2hEYGEi/fv0YNmxYnkKhnxL1EhWklyILFizAwsICQ0NDOnToQKVKlejUqRMeHh6MGzdOlngvVaoU5ubmGg+oRo0a8eWXX9K3b19OnTrFtGnTWLVqFd988w1WVlZab7ZBevGRcwWQ8/qpWbOm/ECcO3cuixYtYujQodjY2Mgeb8OGDWXdQHXb2rVrM3fuXBwcHOjWrRtTp07VuuGvX79Oly5d+Oqrr4iOjpZjiosXL2bw4ME4ODhgb28vryBat26tcc5yeuxq6tatq7E6mDt3LjNnzsTW1pZevXrJv7mNjQ3R0dF07tyZZ8+eYWFhQeHChZk6dSqdOnVi9erVDB48mPDwcLp06YKenh49e/aUz3u9evXkuXbs2JEBAwYwbdo0ihQpgpWVFRUrVsTKyoqUlBS53bBhw7h9+zZdunShcOHCcszrY/Gv0iWMj48XWVlZ79yuXLlyYv369SI9PV2jPCEhQavsvyUuLk5kZmZqlE2dOlU4OzuLtLQ0kZGRobOdSqUST58+zXW/LqKiooRKpcqzTpMmTURaWpq8nZCQoLE/IyNDrF+/XpQrV+6tx/03EB8fL8zNzbWOR+F/l3+tLmHONxvvws6dO8nOzkb/NRn5D6l4m5dMuNo70IW+vj4V1SrOb8mbArVDhgyhS5cuGuO+fqz6+vrUqFGDnTt3vtPY/yShoaFMmjSJRYsWfVZqxQofhn+dwfpv6fYPafEtXbr0Hxk3r7/KV2NgYECPHj0+wWw+HPXq1dP4w0cFhZwo/5ZQQUEh36AYLAUFhXyDYrAUFBTyDYrBUlBQyDcoBktBQSHfoBgsBQWFfINisBQUFPINisFSUFDINygGS0FBId+gGCwFBYV8g2KwFBQU8g2KwVJQUMg3KAZLQUEh3/DZGKywsDBu376dp8jEu5JIIrG8Ww74T4VA8IAHedZJSUnh9u3bb62l+E+Tnp6uJTzyOpGRkXmmjVYLO6SlpensKy0tjUePHpGcnCwrxHxq4uPjP2oa4c8ZDYO1YsUKWrVqpZW98fDhw3Tp0oWaNWvmqkuYnZ2NnZ0djRo10tAlTE1NxcLCQv7UrVtXQ6dOjZOTExYWFjRu3FjOiAiSrlrO9rVq1dJSngEpa2POdK+PeUx/+lP37/9mMYtM8haBfcADHHGUt49whG1s01l3K1tpQAPqUY+2tOU613XWexvWs55IXt1cc5hDNnkb3pe8ZAhD8qwTERHBmjVrGDNmzH89t/fh5cuXjB49mubNm9OiRQv69u2bZ/2wsLBcc7ircXBw4O7du7nu79+/PwB+fn6MHz9ea//du3dZsGABV65ckTPqfmq2b98uKyopvDtyxtEbN26Ihw8fiuLFi2tk+7t9+7a4e/euaNy4sbh165bOjIDZ2dniwoULYs+ePWLAgAG51jE1NRV3797V2ufn5ydSU1OFEEL8+eefYuzYsVp17ty5I0xNTUV2drbWvurVq8vfs0SWaCgaimVimXgpXopH4pHoI/qIGWKGEEKIFJEiUkWqXP+5eC6EEMJNuAlrYS2eiqdynRSRojXWIXFINBKNhK/wFdkiWxwSh0Q5UU48E8/k/rJElrgj7ug8D4/EI/n7S/FSdBfdhbtwF8/EM5EskkUNUUNEiAgRI2KEEEKkiTQRIALEC/Hi1bkU2fJ+IYSIETEiWASLbKF5bkJCQsRXX32lcx4fm82bN4sJEybI2+Hh4Rr7U1JSRGxsrLwdEBAg+vTpI7Kzs0V0dLRG3ZiYGKFSqUR8fLxG1tewsDARGhoqXxPPn0u/5ZUrV4S1tbVcLzY2Vrx8+VIIIURmZqZ4+vRpnnNXqVQiMjJSoyw6OlpkZ2eLe/fuaWWezcjIEHfv3hVZWVkaxySEEM+ePdPIertq1SqxcuVKeV6ZmZni3r17IikpSQghRGpqqoiIiNDoIzExUQQGBv5X2Xg/B3RmHG3WrJlOQUp1nufXc5UHBgayfPlytm/fjp6eHu3atePYsWO5WsYLFy5QpUoVWQh106ZNqFQqxo0bR+PGjeV65ubmHDp0SKv9tm3bGDVq1BuFJM5znjjimMIU9NCjKlX5mZ/pSU8WspA/+INylGM0khZec5oTTjgHOEAggcxjHl/zNY95zFOeMotZGv2vYQ3f8R0WWADQn/444ogzzkxlKuaY8yVfUopS3Oc+m9hEfepzjWssZjElKEEkkSxnOZlkcpvbbGADZSjDV3xFHHEsYAEmmDCb2XzN19ShDve4RwtaMIc5pJJKBzoQRBDeePMbv1GBCoQQwhzmYIVVnufoU5CQkEBycjIvXrygSJEiGvnVp02bxr179xBCUK1aNQ2RUZA0Cy9evEjZsmWJj4+nZcuWhIaGMmLECH755Rfq1q1Lhw4daN68OWlpaXTt2pVBgwbRvHlzrTz4mzZt4uTJk+zcuZOtW7fi5OREmTJl0NfXZ+fOnbIYrZr9+/ezevVqKlSoQHp6Os7OzpQuXZqWLVvSvHlzDA0NCQoKYu/evdSrV4+zZ88ya9YszMzMiI6OJiEhgUuXLhEbG8ukSZMASc/Qzs6OYcOGaYxlbW1N2bJlMTY25uLFiyxYsIA9e/YghKB169bMnTuXhw8fMmHCBKpXr05ISAhjxoyRxYj/F9HI6Z6enq7lYamxsLDQ8LCioqLEoUOHNOocPXo0Vw9r+PDhYvv27fL2jRs3xPXr1zXqvHz5UrRo0UKcPn1aozwrK0tUq1ZN66mnJqeHtVFsFEPFUI39KqESRUVRES2ixUKxUGwSm161FVLbK+KKsBW2cvkWsUX8In7RHktUF8EiWKNspVgpRovRQgghyogywlN4CiGE2Cv2iqliqhBCiAFigAgTYUIIIa6Ja2KskLzIvqKv8Bf+cl+1RW2RJTSfpBkiQzwQD4SFsBCZIlOkiBTRUDTUqJMgEsRJcVIME8Pksn/Sw4qNjRXjxo0T5cqVE7179xbnz58XQggRHBwsbG1fnWdra2vx6NEj2cMSQoh58+aJ1atXCyGEWLdunZg5c6YQQoi+ffsKf39/cfnyZWFtba3l6aivA7WHNXv2bDF27FiRlZUlsrOzRd26deU8+Pb29sLV1VVr3o0bNxZxcXFCCCFmz54tHB0dhRBC1K5dW7i5uQkhhNiwYYNYtmyZEEKIXr16icDAQCGEEI6OjqJ169ZCCGmlsHnzZiGE5IG1bNlSCKHpYbVr106+J1avXi0aNWokhJC8wDp16mjMKyUlRfj4+IjOnTu/+eR/ZnyQnO7ly5eXYwZvIjExkbNnz2rEr16XsMrIyOCbb77Bzs5OS/X45MmTNGrUSEsDThdlKMNtbmuURRBBGmmU4P3zhJehDKGE0oAGctltblOGMvK2JZL4aitasZKVqFDhjjsOOMh1DDB4q/HssCOVVCpRiVhiucc9THglOvuAB4xnPMUpTmlKv1c87UNSunRp1q1bxx9//IGbmxvffPMNQUFBHDt2jJCQEKytrQHp5YC/v7+GB2ZnZ8egQYOYMGECzs7OWnnpv/zyS+rWrUvDhg2xsrJi5syZVK1aVaPO5cuXuX37NgEBARgYGBASEkKFChXkPPht2rTh7Nmz9OvXT24TFRVFZmamnL+/bdu2ODk5yYreao2+WrVqyTJyvr6+mJubA9CiRQscHaU46LFjx8jKypJXHUZGRjx79kzrPLVo0QKQFHnU/RsaGqKnp0dycjJCCIYMGULhwoWpVKkSPj4+7/ZDfEZ8sreEe/bskdWMdZGZmYmNjQ1dunSRZcRy8i66hG1oQyihhBMulx3kIB3piBFGVKYyT5Bkyp/xTP5ujDHpvFm4tBvdOMhBeTuNNI5znG68yit/i1sABBJIE5pggAEWWLCCFbj+/Z+6j9fHzbntjTcZZHCAA/zO7ySTjOCV5hzAZjYzlKHsYQ9f87XW/n8K8bc2npGREX379qV+/fqEhobSpk0bGjRogKurK66urpw9e5bevXtrtK1ZsyZFihTh4MGDFCxYUEv6Sl9fn6VLlxISEkKDBg1YtmyZ1vitW7dmzJgx2NjYkJGRgampKZGRkfKb5MDAQC1V4woVKpCZmSmrd79eRy1ykjMs0ahRI27dkn7vmzdvaoxva2v2JvdVAAAgAElEQVQrH+eFCxd0ipHkFE55XUQFpPz9bdu25a+//mLChAm5Cq3+L6DhYR04cIALFy6QlpbGpEmT6NGjBz169OD69evs2rWLyMhIFi9eTOvWrRk7dizXrl3DwcFBltZeuHAh165dIyQkhEmTJjFx4kRq1qwJSAbn9bcyixYtQqVSMXv2bGbOnImvry81a9Zk0qRJlC1bllmzpNjR8+fPuXbtGvv27Xurg6pIRdaxDkssscWWe3//d5SjAHSnu2y8fPGlKEUBMMec29zmZ36mD31y7X860+lHP5rQhO50xxln7LCT40b66LOQhXzJlxzgAH/wBwATmchoRtMb6eZMI40ZzKAznZnFLFrTmrnMpQtdGMMY2tAGW2y5ylVWspLznKc4xbXmY4EFa1hDJJFc4MJbnaNPwdSpU4mPj6d+/foEBgaSlpYmC6MuXbqU0aNH07Jly1zf6I0YMYL/+7//Y9WqVVr7Tp06xblz56hTpw6nTp1iyBDdb0wnT55MoUKFsLa25uDBgwwaNIj+/fvzxRdfcPr0aaZMmaLVZvTo0VhbW9OmTRsOHz6Mi4tLnsc5ceJERowYgbm5OREREbIHN2LECIYNG8b9+/epXr06169fZ8uWLW88b6/TuHFjvv/+ewoWLIiHh4eslfi/ihzDCgsLE56envLnwYMHQgjpLUfOcn9/Kd6SmJgofHx85HWmt7e3Rr3ExEQhhPTG5cKFC1rr0vDwcHmMW7duabT19vaW68XExMgxgtwwMTERt27d0tDyeyKeiMPisPAUnhpvBYWQ4j1HxBHxXDwXV8QVuTxTZIpr4pp4JB6Jp+KpCBeab7bUqIRKXBVXxQFxQI5LqakgKogYESOOiqMiSSRp7MsQGcJNuInj4rjGvqfiqTgnzsnbd8VdcV1I8b1oES1chasIF+Hy28JoES1aiVZy/WARLI6JYyJBJIir4qoQQojk5GRx7NixfyyGlZGRIc6fPy/27t0rbt++rbU/PDxc7Nu3T/j5+QkhpBhNzt85NTVVeHp6ym/3hBAiMDBQpKSkiBcvXojTp0+Lffv2ydeQEFLsSgjp2gwKCpLLfX19xZMnT4QQQkRGRorz58/rfNus5vnz58LDw0PjevL29pa34+LiRGhoqLwvLS1NBAUFiR07dog5c+Zo9HXt2jVx4MAB8fjxYyGEEBEREfJ3X19f+e14bGysCAt7dS1dvXpVfiv44MEDcfjwYREdHS0f4/8S6hiW3t8GiyVLlvzThvO9mDVrFllZWcyfPz9PjcBPQUUq8gztWMWHIoEExjOeutRlDnNyrRccHMyOHTswMzPTUt1W+HCcOXOGM2fOkJGRwbVr19i0aZMc01L4MPz8888sXbr089El/PXXX//pKcjsYc9H7b8gBZnJTOqTtyR9w4YN8/2DKD9gZWVFqVKlMDAw0Ll8VfhwfDYG69/Ex/4bKGOM32isFD4dhoaGWFpa/tPT+J/gs/m3hAoKCp8/isFSUFDINygGS0FBId+gGCwFBYV8g2KwFBQU8g2KwVJQUMg3KAZLQUEh36AYLAUFhXyDYrAUFBTyDYrBUlBQyDcoBktBQSHfoBgsBQWFfINisBQUFPINGgYrJiaGU6dOsXv3bo1KL1684OLFizg7O5OYmJhrZ/fv3+fgwYOcO3dOLsvMzMTJyUnj4+fnp9U2KiqKzZs3s3z5cry9vTUEUe/cucP+/fu5fPlyrmMPHz4cW1tbObUtSLm2V69ejZOTE1FRUXL5mTNnOHpUyj66dOlSWXDzP//5T679X7lyhZUrV7Jz5863EsG8ceMG27dvz3X/rl27uHjx4hv7AQgPD+f3338HwMXFBU9PTwDmzJlDQkJCru3S0tKwtbXVUmr5VPj4+DBy5EiNz+PHjwkICOC77757635++uknvLy88qyTM43xyJEjOXfuHJ07d85VR1Mhf6JhsBYsWMCBAwe0xCydnJzYuHEj06ZNy1UtV6VSMXr0aJydnVm7dq3GvoSEBPnz66+/6hTCvHv3LsnJyVSqVIlFixYxf/58ua29vT2Ojo5s3bo11wPx8vJi7969cs74pUuXYm1tTUZGBlevXqVZs2Zcu3YNkAzg7duSSMWFCxdkI9ykSROdfU+ZMgU7OzsMDQ05ffo0TZs2JTQ0NNe5gCTAkFNU4XX8/Py05KhyIyEhQb5hq1SpQvny5QEp31WBAgVybVeoUCH27t371obxQ/Po0SPi4+OZNGmS/ClXrhympqZy+uu3YdKkSbn+Nmqio6Pl72vXrqVt27a4urrKKboVPg808mGtXr2ajIwMWQ1Ejb29Pfb29loXTXx8PIGBgbRv3x4DAwPc3d05duyYhqqtkZGRrM0WExPD8uXLZQXg0NBQhBCYmZnRpk0bWTHE0tKSoUOHMn/+fEqWLMnp06fZtWuX7Fm8iYcPHzJ//nwiIiIoXbo0ICmTTJw4kStXruTaTtfT2NfXly1btvD8+XPZOCxZsoRp06bh6uqKi4sL+vr6uLm5UbFiRSZOnEipUqVITk7m+fPnAAQFBbF161bu379Px44d5fOh5sqVK1y9epVJkybx9OlTtmzZQkpKCmPHjqVWrVoadWNjY2V164cPH5KVlQVIDxt/f3+aNm3KsGHD8jSWn5LSpUtjYWGhURYcHMymTZv4448/NMp79uzJjh07KFNGUh/q1q0bBw4cYNOmTfTs2ZNWrVoRFBTEH3/8wb179+jQoQMzZszAyMhI7iMmJoZhw4aRnp5O2bJlmTJlCl9++eXHP1CFT8J7xbDu37+vU60kN3bs2MGgQYPkG//48ePy0gykC3nJkiU4ODi80xP4dby9vbG0tJSNFUCvXr24ceMG6em5q+Ls2rVLq8zLy4uuXbtqeDJ9+vThwoUL8lizZs1i3Lhx1KtXT1Z/CQ8P59KlSwD88MMPDBkyhB07dtC2bVuN/g8fPszs2bMZPnw4L168oHv37nTp0oWvv/6agQMHolKpNOr7+PjICi2urq68ePECkBRatmzZgqWl5Tsttz42Hh4eWFtby5/MzEzS0tLkZXhOLC0t2bt3LwCXLl2iUKFCFC9enKdPn8pKMePGjWPWrFl4eHiQkpLCyZMnNfooXrw4rq6ueHp6smTJEhYvXvzxD1Lhk/FeGUebNWuWp9Lz62zdulW+IAF+/PFHjf2FCxemfPnysrLu22oevo56aZmTkiVLUqBAAfkGf5++KlasSGpqqixjZW1tTePGjWncuDHLli0jJiZGo365cuXYunUrtra2smoMSAa8cOHCHD16FGNjY3bv3k21atXw9/cHpCWdp6cnZcuWfeM8S5QowZo1a7h//z4BAQEkJiZSosT7azC+L61atdJIG5zTG3qdESNGMHToUOzt7TW0ANXcvXuXO3fuMG3aNACePXtGTEwMffq8UjgyNDRk/vz53LhxA0NDw39sOazwcfhkKZKvXr1KkSJFaNiwYa51atasSc2aNbG1tcXExITp06djaPjuUzQzM2Pq1KmoVCoMDCSxUi8vL4oUKaLhdb1tXzmXuCBJTJmamsradIULF5b3GRsbaxnF/fv34+bmxpYtW/jll184c+YMAKVKleLhw4ekpqZibGxMbGwsJUuWpEaNGgCy/PnrBvB1njx5wvjx41mzZg21a9fGy8vrX2OwjI2NdWrx6aJ27doUKFAAHx8fPD09Wbduncb+0qVLU758eZycnOQy9e+r5ujRo8THx3P8+HESExOpUKHCex+Dwr8HjSXhy5cvSUxMRAhBQkICaWlpgPSmLyEhAZVKRXJysnxDPnnyhB07dsjt1fty1lezdetWrSfmpUuX5CdgSEgI6enppKenc/DgQZo3by4bq6SkJFJTU8nIyCAhIUHjDaIu2rZtS/369Zk8eTLPnj3j6tWrzJkzR34yvwt9+/bFwMCAOXPmEBcXh4eHB0uXLtXoy9XVlbi4OHx8fHjx4oVW/OjO/7d37nE5n/8ff94V2pBTzQwty6GvySGHb5QOZKo1IcnmUE7baGaMorYcZk5ffhhmaaPGyLmGr5Yktpk0Ko05hZJDLFKk8+f3x8f90V13yRcpj+v5eHio677u63N9Pt2f131d7891vV/nz/Puu++ydu1arly5osSdXFxcmDVrFs7Ozty8eZNhw4aRlJREhw4dcHR0pEuXLhgYlPUhLM25c+cwNjamW7duHD16tFo9GUtNTVWMRMPCwsjIyKiwvpeXF8OHD2fAgAFlRmONGzfGzMyMRYsWcenSJY4dO0ZsbKxGHT09PS5dukR8fDy+vr5ajUkFNReN4UtgYCBhYWFYWFgwcOBAPD09GT16NNHR0SxYsIDGjRszffp0evToweLFi8nMzOTo0aOMHDkSgI8//liJTQwcOJBVq1bRoUMHiouLlRuyJMnJyRQVFWFtbU1cXJzyJM7a2ppvvvlGqTdq1Cjl8f3AgQNZv379Y5/+REREEBAQoLhNjx49WontNG/eXFn+YG5uTt26dQGwtLQs006tWrX49ddf8ff355133qFhw4Z88cUXuLu7K3VsbW0ZOXIk9evXVwTc0NBQcSv29/dXRk/z5s1DT08PU1NTmjZtSr9+/ahTpw6zZs3im2++YcWKFQQEBJCWlkaDBg1YvXo19erVU2yj3nzzTcVGXZIkVCoVNjY27Nq1iz59+tClSxcmTpyIvr5+hdenKjAzM6N3794ay1i6dOnCG2+8wdChQ7W+x93dndTUVEaNGqWUDRgwQHn4sHnzZqKjo/nuu+9o1KiR8tlTP8hwdHTk9u3b/PjjjwwbNgwzM7PndXqCF4RipFqTadCggeTh4aGYUlYVPj4+UkhISJUeU5Jk09FOnTpVaAb64MEDycPDQzIwMKjCngkEzx61kepLY/OVnp6OJElVPrIwNjbGyMioSo8JMGnSJPz8/JQ4mjb09fUJDg6usI5AUJN4aQTrRbk9e3t7v5DjVrSItiTVYWooEDwrRERSIBDUGIRgCQSCGoMQLIFAUGMQgiUQCGoMQrAEAkGNQQiWQCCoMQjBEggENQYhWAKBoMYgBEsgENQYhGAJBIIagxAsgUBQYxCCJRAIagxCsAQCQY3hpRGsc+fOcebMmcdmI30sV6+C2qiiqjJ3pqZCYSEUF4Pa+isrCx6TGvmJuX8f1P6M6eny709IamoqZ86cUUwhKiInJ4eUlBSNsrS0NCUX/vPiwoULxMTEEB8fz/Hjx7XW2bVrF/fu3atUewkJCSQlJVWqbmRk5GNTWlc3Dh8+TFpa2ovuRqXQEKylS5fSs2dPzM3NNSqFh4fj4OBAq1atyk2/W1xczKhRozA3N2fixIlKeU5ODp07d1b+tW3blsDAwDLvP3jwIO3atVPqrV27FoAjR45gaWlJp06dcHJyKtdQs1evXoSGhsoWWHl5YGICc+c+qpCaCq1awXffVXxFfH3h3Dn55ycxwbh2TT7mqlWPyuLj5bJt2yp+7wcfyAKSnQ0DB8plv/zy+L4+KUeOwH/+I/88dy4cOvTETURFRfHBBx9w9OjRx9aNjIzExMREw6jE2tqarKysct8TExPDvHnznrhfJcnKyuL69etkZGSUKx4LFy7k9u3blWovMjKSqKioStWNj4+v8Pyqkm3btmm910pz6tSpGiOyGoJlZ2fHli1bSE1N1ahkZmZGYGAgDRo0UDzxSqNSqRg/fjz+/v4appavvvoqCQkJJCQkEB8fD4CDg0OZ9z948AAHBwel7ocffghA06ZN2b17N4mJicydO5fJkydrPX69evWYPXu2nBeruBhyciA8HNR55X/8ERo2lEcuai5ehNLfLKtWwb/+Jf984MCj8sxM+OsvuW1tFBaCri5s3PioLDgYGjUC9Te5JMH583DjhvY2SvLee1DKv7BMX+/cgYICuHQJ8vMfld+7Bw8eyCJY0hna1hYCAsoeq6gI/v5bbq80ly/D6dPKdRwzZsxjTU1L0qtXL2bNmlVmVBUbG8u1a9eU30+dOsXZs2eJjIzkt99+IzQ0lIsXL2q85+LFiyQlJbFv3z5CQkLIysoiLS2NdevWadiG6evrk5mZSU5ODnZ2do/t4+nTpxUBLigoYMeOHVrdyUH2Ldi5cyfFxcXcunWLzZs3s3LlSv766y9AFmR1CuuSXLt2jZCQEL799lsNI+H09HQ2bNhQoWBcu3aNjRs3ariux8TEcPXqVTZs2KD1y6OwsJD9+/dz8OBBQkNDFQPkjIwMNmzYoHhmguyaXVmjkBeNhmB17dpVa8fbtWuHqalpmcyVSUlJSu5tlUpF7969qVevXrkHO3z4MM2bN8fU1BSAtWvXsmbNGuX1c+fOsXbtWo0PsqmpqZLRs127dly+fLlyUwo9PejbVx6pAOzeDa6uj15fsAAWLoSZM6F/f3houMHo0bIwAajtz0+dksu/+w4cHOS2tFGvnix2cXGykPzxB5S8YWbOhP/7P5gyRe5LReexc6fcR4DffpPFZto0+ZzUI8Dhw+Hdd+HLL6F3b/jvf+XyhQvByQk++ghcXECdHz8qSu5DaT78EL79FsaPB7WnoSSBvb3c1sqVEBRUfl8roG3btlhYWLB582aN8uTkZBYtWqT8PmHCBPJLiq4WoqOjGTp0KCdOnOD48eMMHTqUmTNnUlRUhL29PXceCm5kZCRGRkZcvHhRa57+kkRERDBx4kRatWrFuXPncHBw4J9//iEoKIjp06dr1L1+/TouLi4YGBigUqlwcXEhLy+PFi1acOrUKUCepZR29M7Ly8PZ2ZnatWtjaGiouI6vXr2ayZMnU1RUhLu7u1ZLsh9++AFPT0/u3btHnz59lBnG119/zZgxY8jJyWHu3LllnJ20sXv3blxdXcnJyWHQoEHs2LEDgKCgIE6ePPnY91cHnirjaNOmTZ/IO/CHH37QcM7p2rWrIj7NmjWjX79+3L9/HxcXF7y9vRk7dqzG+6dOncq0adMqn/LX0xPmzAEDA1l8SmYlVd+4167JN+X+/fKoRhtvvw27dslTtqQkuX55dT095ZGVg4MsJiW+FVm4UP4/LQ1mzIDYWHjMDQXA8uWwZIl8Dj/9BOvWPWrLwQF8fORR1pgx4Owsl7/+OoSGyiNCMzOoKDPqDz/I9dLSwMtLvib5+bLorlihed3+BwICAnB0dNQw7hgyZAhz5swhNzeXixcvUlxcjLm5OSkpKWRnZ5cxLFHTqVMn/P39ycvLo2HDhpw/f54WLVrw999/ExUVhbu7O5MnTyYpKYmcnBxeffVVjh8/TteuXcu0FRwczJ9//smePXuoV68eq1evxt3dHVtbW2xtbRkyZIhixHrmzBnc3NxYs2YNnTp1Ij8/n6ysLFq2bImNjU2Ffov37t2joKAAY2NjLC0tFWuy4OBggoKC0NfXp06dOlqNdtetW8fmzZsxNjamefPm/PTTT/Tu3RuA8ePHM2TIEDp37szy5cvx9PRU3qenp0f37t25deuWci1DQkJYsmQJlpaWdOvWjTlz5uDm5laZP2G14amC7q+99lqlBevu3btERUUxZMgQpaxr165069YNkN1UfHx8mDJlCqGhoWU86fz8/CgsLGSmthFCebz9tnzzLVsmj5BKEhIijz4CAuDMGXlUVB7p6bL4jBsHW7bAn3+WX9fWFo4elUckJT5AgHzzDxggx48uX674mCX59VdQ33DW1vJISY16FNiqlfyQ4KGFmFKuowOtW8tCWx4zZsCQIbIIZmTI52diIotf584wahScPVu5vmqhZcuWvPPOO3z//fdKWe3atRk0aJBiRf/xxx9Xqq02bdoAckrspk2b0qJFC0C2AFNPc5ycnNi+fTt16tShfv365cZdd+zYgbOzszIriIuLIy4ujuDgYIKDg3FxcVHcmo4ePUrjxo1p37690v/NmzcTGhpK586dNbwSS9OkSRNlNtG5c2fCw8PJzMwkOTmZ0NBQgoODSUxMLOPZKUkSycnJyjmamZkpJrvq30F2aCoZhimPkydP0rZtW0CerdSUUVVJqiyn++bNmxXLrceRn5+v8Y01e/ZsUlJS2LBhw5MbKnh5waZN8g0fGfmofPFiOHYM6taVp04VTc9CQmTBmjgRjh+HUtMbDVQq8PCQxeihISogj2BWr5ZjRbq6MHhwxccsibm5PA00M5OF56HIA3J8yd4ebt6E116Tp8LqcjXJydCunSzepfnnH1kA1SLcteujfvn5ySPRrVvB3x+2b69cf7Xg5+eHlZWVYq8G8NFHHzF8+HBu3bqlTA+bNGmiiMT/QmZmJlevXmXu3LkUFRXx5Zdfllt369atTJ06laKiIry9vRk8eDDXr18n4GGcr7i4WPE19PLyQk9Pj8GDB7N9+3Zq1apF586dCQoK4ubNm/Tv3x8vLy+txykuLsbKygorKytOnjyJr68vrq6uWFhY4OXlpQhP6SfcKpUKa2tr/vjjD6ysrIiOjsbR0bHS18LQ0JDz588rvzs6OhIdHc2QIUOIjo6mf//+lW6ruqAhWNu3b+fw4cPk5uby2Wef4ejoiKOjI3Fxcfz0009cvXqVBQsW0KtXLz766COOHTvG9OnTOfTwadPXX3/NsWPHOH36NJ999hmTJ09W/AN/+OEHjXgVwPz585UP1ZIlS7hz5w7FxcXs3btXGUnt2LGDxYsXM3bsWMXa/uuvv1a8BB/LuHGP4jIl+de/4Isv5J+PH5djPuXRubN8wz54ID9Zq1274mP6+JQt09GBZs3kKerNm3LAvxIBYUCOMY0dK09Dd+yQR2pqtmyRg+X792ue54kT8hPP5GTo1w/K+6Jo0kRe3rBokSyG6qUOx47JU8oOHeS2KzN1rQAjIyM8PDw0ngC2atWKBg0a0KtXL8VEpHv37mRmZtKnTx+mTZuGs3qKW0kaNmxIp06dcHZ2JiMjo0L/yldeeYVdu3bh4eFBXl4e48aNY/r06bz77rsYGBiQmZnJvn37lPqTJk1CX18fV1dXli9fzvDhw2nfvj3p6ekVmpGcOHECb29v2rVrR1paGp9++ikAX331FX5+fujp6fHgwQNsbGzKxM18fHwICAhAV1eXOnXqsHz58kpfCzs7OwIDA7G3t2fhwoVMnDgRHx8fZTRYMoZYU1Ah+xKycOFCzp8/r/G0xcTEBBMTE9LT0/n777+V8saNG9OxY0eysrJITk5WnhrFxsZqfINaWFhgYGBAcXExv//+uzL3VpOSkoIkSZiYmCgOzbVq1cLe3l4ZiV27do1z6iDzQ6ysrMrEDFq2bMn+/ftp27atPM+NjYWePTXPNjVVHgG1bClPnQ4dkm9kU1NZjExM5AD7m2/KcZsuXR4F4C9ckEdHvXvLU8jSN3BeXtnRD8iCUbeuHFPKy4ODB8HQUP5dpYLmzeXlD2+/LY+84uPlNm7elMVDfcPduycvS7C1fRRTcnaWA+6ZmdCxo9wWyEJsYgJt2kDjxvIIDeD2bXnK16aN/LSySRP59Xv3ICYG3npLFuNGjaB+ffl46enydXg4lUhNTWXq1KlMnDiRPn368DRIkoSlpSWbNm1SHsQ8K7Kysqhfv/7/ZHGWn59PdnY2TZo0qbBeQUEBGRkZNG3a9LHHyc/P5/bt21ofat29e5datWrx6quvlvt+dTzuWfAs26oqZsyYoQjsS2Gk6u/vL/n6+kq5ublP39iDB5I0bpwkTZny9G09T5ycJOnEibLl/v6S9P33z+WQa9askXx9faULFy48VTsXLlyQbGxspICAgGfUM8HLzEtnpPq0iw010NWFSZPkUUt15quv5IB6aTw94Tl9g1Y2OP44TE1NlVCCQFBZXhrBeqbUqlX9xQoePTkszcMnaQLBy8ZLs5dQUP25dOnSE+0jzM/P/5/3uKWlpT12IWppylv+IKg+CMESVBlOTk5PJCIpKSl8Vnp7UiX5/PPPy2ztKc38+fM1NnE/ySJowYtBCJbguXPx4kWte1Dv37+vsQG5sLCQzMxM8vPzOXXqFG+99RZBQUFIklRmYWRGRgZF6n2iUGYkFhgYSOuH8b1bt25RXFyssYfv/v37hIaGkpqaqrR9oOTeUUG1RAiW4LmhXlCp3ppTMouBr68vnp6ejB8/nilTpgBypgNbW1v69OnD999/z4ULF3j//fdRqVTY2dlx4+Gm8ezsbHr06IEkSRw6dAgbGxumTZuGg4ODMq0bMWIEZ8+eJS8vj7fffptBgwYxe/ZsunXrRk5ODkeOHOH69essWrSIZcuWAfIaMEH1RgTdBc+N7du3079/f6ZOnUpycrIy4jl9+jSpqalsf7hyftCgQVy5cgWQp4H//PMPenp6nC2xHWjEiBH89NNPfP7552zduhU3Nzf09PRYunQpK1eupFOnTqxfv56QkBDmlkwrhDzCWrlyJcbGxnz66afExMTg7OyMsbExS5cupXHjxlV0RQRPixhhCZ4b0dHR9Hy4eLdk1o09e/Zw+vRpBg4cyMCBA8nOzlb2yP373/9GT6/s9+jIkSPZ+DB1T3BwMKNHj0aSJGJjY+n48ImutbW11rxVLVu2xNjYWOlH6YXIgpqDGGEJnhtdu3YlKSmJnj17cuPGDSVWZGVlRXx8fJmUM3FxccoWndK0aNECIyMjtm/fTlFREf96mLOsXbt2XLp0ibfeeoukpCRlM31J1PsBS/PKK6+Qp84uK6gRCMESPDfc3d0ZOnQoN2/eJDY2VtnqYmVlxaJFixg/fjyWlpYkJCTwySefPLY9Ly8vxo0bx+LFi5Wyjz/+GE9PT5ydndmxY0eZ/aoV4eDgwKRJk7CyslLiaILqz0uxNUdQPcnNzZX27NkjXbt2TYqNjZWKi4uV1y5fvixt2bJFSkhIkCRJkrKysqSkpCTl9ZycHCkxMVGjrYMHD0r379/XOEZWVpYUGRkp5eXlKWUnT56U7t+/LxUXF0t//PGHUp6WliZduXJFow/q10vWE1Qv1FtzNDY/CwQCQXVEvflZBN0FAkGNQYQ55q0AAAtcSURBVAiWQCCoMQjBEggENQYNwTpw4AAzZ85kwoQJGpWSkpKYN28eo0ePVuyCSiNJEuvWrWPSpEmsXr1a47Xz588zc+ZM3n//fTZs2FBuZ8LDw3Fzc2PKlCmKpVFBQQFBQUF4e3uzfv36ct/bpk0bhg0bpiQQLCwsZMWKFQwePBgvLy/279+v1A0ODlZyxo8YMUJZl9OjRw+tbefm5rJgwQJcXV0ZN24cf/zxR7n9UBMREaGk2tXG3LlzFdeSx/HXX38p5h3Lly9n06ZNALi4uGjYNWnr97Bhw5QFm1XNiRMnGD16tMa2mmnTpvHgwQPu3LmjpOjdtm0b/1H7JVaAiYkJt27demYr0o8ePcpHH31UpnzOnDns3bv3mRxD8GzREKyUlBTat2+v3BBq0tLSaNasGb/++quGN1pJJEni6tWrGBgYEBMTo/Ha2LFjsbS0ZOnSpXz//fda8yDFx8czY8YMZs6cib6+PiNHjgTkHfu3bt2idu3a/P777+WeSEFBAaGhoUqmUg8PD2JiYvDz88PJyYnJkycrCw9zcnK4/zAV8J07dyh8aNygzSpJkiT69evHmTNnmDdvHr169WLEiBH8orYPKwd1GunyyM7O1sjOWhGFhYWKhdX777+v5PVetmxZhau09fX1CQ0NVc6vqklNTWXnzp3Mnz9fKdu+fTv5+fkYGBiwcuVKQF5eoP57V0RiYiKGhobPbM9ffn6+1vzx48ePL+NeI6geaAjWmDFj8PDwKFPJycmJsWPHUr9+fY3ylJQUJce0jo4OX375pbKyuSRXr16ld+/evPHGG3Ts2FGxL//ll1+IiIgAIDQ0lGHDhin2Q5GRkdy9e5e6devi5+endUFgecTHxxMZGUloaCjdunXDw8ODRYsWVWhIAHLO7tL88ssvXL58mZCQEMzNzRkzZgwzZ85k1qxZACxZsgQfHx/s7Ozo37+/IqpxcXH8+OOPgHyTOjk50bdv3zLWZQArVqxQ2gsLC2PQoEE4OTmxTYtj9K5du4iOjgZk+6w7d+4gSRIuLi7Y29szYMAA5ZpWBwYMGEBUVFQZc97s7Gz8/PwA2a9Sfa7e3t74+fnRu3dvhg4dqnj4HThwADc3N+zt7fHx8dHqEpOXl8fixYuxs7Nj1KhRilfgjz/+iK+vL/3798fKyoqwsLAy7z127Bju7u5kZmayceNGYmNjAVlMFy5cSK9evfDw8CAjI+PZXRzBE/NUMSx1nurHsW7dOuzs7HjnnXfIzs5m6NChgOzXdu+hK3JqaqriHlK7dm1MTU018ss/CYmJifTt21dj1XTfvn25ceNGhTbi2vIhJSYmljFCcHZ2JikpSckiEBcXR0REBIGBgUpGznv37pGeng7I2VC3bNnCgQMHNKbLkiQxffp0Ll++zOzZs7l+/TrLli1j8+bN7Ny5kxUrVijXR01GRoYyKkhJSaGwsBCVSsWmTZs4ePAgGzZseLbZV58SPT09/P39mT17tkZ5UVGRYjh69+5dxfk4LS2N9PR0Dh06xIQJE/D19QXkjclRUVHExMRgYWFBaGhomWPt3buXM2fOcODAAcaNG6csBr19+zb79+9n586dhIeHl7k+e/fuZcaMGXz77bc0bNiQmzdvkp2dDcififr163PkyBHMzMzYXZ6JrqBKeCrBatOmTZmNptpQx8UCAgJITU1Vpoxubm6KT6Gurq7G1KWgoEAxnHxS1C4kJcnPz6eoqOiJ29TWVm5uLrq6uorxgLOzM/r6+piYmNCoUaMyeZiGDh1K3759mTt3robABwQEkJeXx7Jly1CpVGzdupWsrCy8vLyU2E9lR0vr16/H1dWVkSNHcubMmQpjW1WNh4cHiYmJGkYmFTFw4EB0dHSwt7cnKSmJgoIC7t69i7e3N05OTmzdulXrtDA8PBx3d3d0dXWxsbHh4sWLSgjjvffeo27duhgaGpKVlaWkuzly5Aj+/v7s2bNH2etYmg8++ACQY5xxlfWSFDwXnvtTwitXrnDz5k0mTJiAtbU1np6eWgOab731ljL8z83N5cqVK4qB5JNiYWHB4cOHlTgVyPblrVu3rrw92EO6devGvn37NDzj9u7dq+EkXHKacOfOHRo1aqTRhp+fHxEREbRo0QI7Ozsl66anpyeHDx9WboJmzZpha2urGHkmJiZWKqlcQkICBw8eJCwsjLCwMPT09MjNzX2i83yeqFQq5syZwxdqW7XHoL6e6i+GWrVqsXDhQhwdHdm3bx+ffPKJ1vNr2rSpMlIrLCykqKhI+XuXdInR0dFR/p5du3bFxMSEwMDAcvujjovq6elp5OASVD0aewlPnjzJuXPnKCgoICwsDDMzM8zMzLhy5QrHjx/n7t27HDhwgDt37tCzZ0/OnDlDYGCgkk8oKiqKo0ePcvXqVcLCwrCxsaFly5bUq1ePNWvWYG5uztq1a5V4zaZNmygqKmLkyJGMHDkSJycnunTpwu7du/Hw8FA+bPv27eP48eOkpKQQFhZG3759y8TTStK+fXvGjh2rxDuSk5P59ttv+e677574Atna2mJnZ0ffvn2ZOnWq4gxcMr60e/du7O3tOX36NEZGRmUEKygoCFtbW1q3bk2DBg0UwWrdujXh4eEMGjSIVatWMWDAAAICAujevTuWlpbEx8djZWX12D7q6elx7do1EhIS2Lp1q4ZQVxdcXFxYsGCBktOqIoKDgzE1NWXHjh3069cPkM8xMTGRRo0asWrVKq0ZHdzc3PD29ubNN9/kv//9L/b29lrrlaROnTps3LiR4cOHk5ub+2TO4oIqRxeYbW1tjYODA3/++ScJCQlYWVlx48YNDA0NMTEx4fLly8TExNCpUydycnJQqVR07NiR3NxcsrOzsbCwAOS0IXl5eZiamnLjxg06dOhAgwYNeO+99zh79ix//vknH374IX369EGlUnH79m0MDAwwMTGhSZMmymjG1NSUr776SvmwhYWFoaOjg7GxMTdu3KBLly5lRkrLly/XSKfr7OzMa6+9xm+//Yauri7z58+nV69eyuvNmzenZcuWqFQqzM3NqVu3LiqVCksthqHu7u7UqVOHw4cPY2BgwNKlSzF/6PUXFRVFnz59OHfuHA0aNGDJkiXo6emhUqkwNDSkdevWHDlyhJ9//pmsrCz8/PwwMjJCpVJhampKu3btcHFxISIigp49ezJmzBhOnTrFtm3bqFOnDj179qR27drUr1+fDh06oFKpePPNN2nWrBmBgYF4enpiYmKCoaEhP//8M9bW1tjb29O5c2f09fW1XpuqxMjISIlNWlhYYGRkpAhJrVq1lJHq66+/jomJCaGhoYwbN45Dhw7RvXt3pk2bho6ODt27dycpKYmkpCQ+/fRT5QFOSVq0aIG9vT3h4eH06NFDeS9oppgBOY2Njo4ODRs2xNzcnMGDB3PixAmaNWtGw4YNad26tfJ3srS0REdHB5VKRePGjRW7d0HVERUVpTzQeik2P9va2kqurq5lNsY+b3x8fKSQkJAqPaYkSdLBgwclCwuLCuvk5ORIrq6uko2NTRX16ukZMGCAFBsb+6K7IahmvHS+hKXXflUVdnZ2NG3atMqP+/fff7Nly5YK67zyyitaH+FXZ9zc3HjjjTdedDcE1ZSXRrBeFE5OTi/kuKV3I7wsjBo16kV3QVCNEXsJBQJBjUEIlkAgqDEIwRIIBDUGIVgCgaDGIARLIBDUGIRgCQSCGoMQLIFAUGMQgiUQCGoMQrAEAkGNQQiWQCCoMQjBEggENQYhWAKBoMYgBEsgENQYhGAJBIIagxAsgUBQYxCCJRAIagx6unq6dyMiIgwA1YvujEAgEGgjIiJC0tXTzVLpt6jnU3DjgV9RYVGDF90pgUAg0Iaunu7dWq+/Mv//AboKviD123XOAAAAAElFTkSuQmCC
!usage
{{{[img[clipcalc.png]]}}}
[img[clipcalc.png]]
!notes
Image of calculator
!type
image/png
!file
!url
!data
data:image/png;base64,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rVopQD355JMey1+oGsoLlB5po1y/fj0zZsygoKCAqKgoxo4dy8SJE/n3338BaNOmDcOGDaN3796eyI758+ezYMECtm/fjsFgoEOHDgwfPpzu3bvbztm0aRNTp05l/fr1AHz88cf873//sx1PSEhg4sSJTkfil/Lqq69SXFxMjx49yqQP8Pbbb/PHH3+glCIxMZGXXnqJiIgI8vLymDBhAocPHwagadOmTJo0CaUUq1atIisry2l+BoOBjh070rRpU4fHCwoKeOONNwB46qmn+TOgnAAAIABJREFUCDhrKeF3332X3377DaUUCQkJjB8/noSEhDLPx8fHM2HCBOJOr2M8b948Jk+ejE6nY86cOfTr14+QkBDGjBnDQw89RPPmzbn88stteYwZM4aioiKuueaaMnm3atUKKLlZ4WwCAwMZM2YMjz32GG+99RajRo0iMDDQ6ftwNpMnTwbgwQcfJDIyssyxCy64gKeeeorBgweX6bUMCgqiSZMmHDp0yKGmyrB8+XKWLFlCREQEEyZM4KGHHnJ6rk6n45lnnmHw4MF88MEHPP300w4HMws+gCdqlIMHD7ZdhgQEBJS5LLHf7r//fqdpuFOjzMvLU1dffbXDtHU6nRo5cqTt3FGjRjk8z35zp5bRqFEjBagvvviizPOFhYW2S83SbeXKlUoppTZu3HhOXnv27FHffPONS02ASkpKUlar1aGe9evX2y7nCgsLyxwzm80qLCysTFpff/21MpvNtkv10s3+kr1p06YKUJMnTy6T3v333+92O+j+/ftVw4YNFaCmTp3q8JycnBxlMBgUoH755ReXaZayfft2pdPpVHBwsDp+/Ljbr/v8889tnw1PtC0XFBSoJk2a2DwuWrSo3BqlUiVlEhUVpQD1zTffnLcGoeqo8hrllClTuPjii3nooYcwm80EBwfzxBNPcN1112E2m1m+fDkffvgh06dPp2vXrpXuBRw9ejRr1qwhKiqK/v37c9ttt1FUVMS8efNYtGgR77//Ps2bN2f06NFMnDiRyy+/nClTprBhwwbuuusurrjiCltatWrV4rrrris3v+zsbPbv3w+U1IrtCQwMZO3atVx11VXk5OTw3HPP2WrMnTt35vPPP2fQoEEYDAYWL15MkyZNiIyM5N577+XkyZNO89Tr9Vx55ZW2OwLOZvPmzQA0a9bsnBqZwWDgt99+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7dHry05ylJGRwU8//cS2bdsIDAykdevWXH311QQHB5er7/vvvyctLY1u3bpx4YUXupz0AUomWmjQoAEZGRl88sknZRr4z+aSSy7ht99+Y8KECbzwwgsu064sCxYs4LbbbiM8PJwDBw4QExNjO7Zr164yHT4tWrQAID09nW3btmGxWDAajbRt2/acgdvukJqayo4dO8o9Jzg4+JwJK9LS0mjUqBF5eXl8++23DieRKKWwsJBGjRpx/PhxlixZ4rK5ZsuWLZw6darccxo0aOCyM6gi7N69m6NHjwIQEBBAq1atypQDlDT3NGrUiLS0NGbMmOF02JTgHezft499KSk0sxsOZ4tdBw8cUI62H1avViluDsdQqmyN0t8YP368AlTLli2dnvP999/bLsPOvsXO01gsFtWsWTMFvjPhwrPPPqsA1bZtW6cdVaWsXbvW1lTj6lxv5p133rFdjZx9c4DgfaTs3at+WLOmTBwsrVF6ZD7KP//8k2effRYoGaQ9dOhQxo4d67HbxrRmzJgxdO/enZ07d5KWlmZ7/uOPP+aee+5h6NChPPjggwDEx8ezZs2aKtWj1+v5+OOPiY6OZu3atVWal6f49ddfCQ0N5c0333R6hVFK165dee+991izZo3Lc72ZX3/9FaPRyJtvvlmh2zUF70N3sKQmeA7/7d7NBY0bc4EblyuDBw/m888/P+f5RYsWOR1b5msUFBSwefNmLrroIqCk9zcmJgaTyXTOuW3btq30eNGK8N9//xEeHu60196bOHbsGFlZWbamgJrAqVOnOHr0KG3bttVaiuAG+1JS2LdvH82aNbM9V9rs55HhQa+99hqXX355mSE4sbGx9OnTxxPJewXBwcG2IAkl7VLff/89f/zxR5k21oCAAHr27FktmuwL1NtJSkryiYDuSWJjY4mNjdVahuABPBIo69aty4gRIzyRlE/RrVu3czotBEHwP5y2UQaHhGA2m6tTiyAIgmaYzWZCnIyccVqjjIuLIz8/nwP7958zPEcQBMGfsFqt5OfnE+tkiW6ngTIkJASdTkdOTs45k8MKgiD4E2azmdDQUKeT35QbAYODg8sdxC0IglATkGtqQRAEF5SpUUpbpKA1zm5nFQQtkcgoCILgAgmUgiAILpDubMGrkOYfwRsJUMrhrd6CIAjCaaRGKQjViMVi0VpClWAwGLSWUKWUCZTS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
/***
|Name|ColPicker|
|Version|0.2|
|Author|Petri Salmela (pesasa@iki.fi)|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer.|
|Description|Colorpicker widget as jQuery plugin.|
!!!!!Revisions
<<<
20131219.2251 ''Version 0.2''
* Hiddable picker, showable input, preview
<<<
<<<
20131218.2251 ''Version 0.1''
* Project starts.
<<<
!!!!!Code
***/
//{{{
/**
* Colorpicker (jQuery plugin).
**/
(function ($) {
{ /*** jQuery plugin ***/
$.fn.colpicker = function(options){
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on Colpicker' );
return this;
}
}
var methods = {
init: function(params){
params = $.extend(true, {
}, params);
var picker = new ColPicker(this, params);
//picker.init();
},
getdata: function(params){
var $place = $(this);
$place.trigger('getdata');
var data = $place.data('[[colpickerdata]]');
return data;
}
}
}
{ /*** Color picker class ***/
/******
* Class for color picker
******/
var ColPicker = function(place, params){
this.place = $(place);
this.options = $.extend({
width: '100%',
showInput: false,
hiddable: false
}, params);
if (this.place[0].tagName === 'INPUT') {
this.init();
}
}
/******
* Init the color picker
******/
ColPicker.prototype.init = function(){
if ($('head style#colpickertoolstyle').length == 0){
$('head').append('<style id="colpickertoolstyle" type="text/css">'+ColPicker.strings.css+'</style>');
}
this.id = this.genId();
this.place.addClass('colpicker-input');
this.place.after('<div class="colpickertool-preview"><div class="colorpreview"></div></div>');
this.preview = this.place.next().children();
this.place.next().after('<div id="'+this.id+'" class="colpickertool">\n'+ColPicker.strings.svg+'</div>');
this.picker = this.place.next().next();
if (this.options.hiddable) {
this.preview.addClass('colpickertool-hidebutton');
this.picker.addClass('colpickertool-hiddable colpickertool-hidden');
}
var maxwidth = this.picker.parent().width();
var maxheight = maxwidth/2;
this.picker.find('svg').css({"max-width": maxwidth, "width": this.options.width, "max-height": maxheight, "height": "auto"});
if (!this.options.showInput) {
this.place.hide();
}
this.getColor();
this.initSelected();
this.initHandlers();
}
/******
* Get color from input-element.
******/
ColPicker.prototype.getColor = function(){
var color = this.place.val();
if (color[0] === '#') {
this.rgb = color.substr(0,7);
this.opacity = color.substr(7,2) || 'ff';
this.color = this.rgb+this.opacity;
} else {
this.opacity = '';
this.rgb = this.colornames[color.toLowerCase()] || '';
this.color = this.rgb;
}
}
/******
* Set color to input element.
******/
ColPicker.prototype.setColor = function(){
this.place.val(this.color).focusout();
}
/******
* Change the color of opacity/transparency selector.
******/
ColPicker.prototype.setPickerTransCol = function(){
var color;
if (this.rgb !== 'none') {
color = this.rgb;
} else {
color = '#000000';
}
this.picker.find('.color-transparent').css('fill', color);
}
/******
* Set the selection attributes to highlight selected color/opacity
******/
ColPicker.prototype.initSelected = function(){
this.picker.find('[data-selected-color="true"]').attr('data-selected-color', '');
this.picker.find('[data-color="'+this.rgb+'"]').attr('data-selected-color', 'true');
this.picker.find('[data-selected-opacity="true"]').attr('data-selected-opacity', '');
if (this.opacity.length > 0) {
this.picker.find('[data-opacity="'+this.opacity+'"]').attr('data-selected-opacity', 'true');
} else {
this.picker.find('[data-opacity="ff"]').attr('data-selected-opacity', 'true');
}
this.setPickerTransCol();
if (this.color[0] === '#') {
var rgba = this.hex2rgba(this.color);
this.preview.css({'background-color': 'rgba(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ',' + rgba[3] + ')'});
} else {
this.preview.css({'background-color': 'transparent'});
}
}
/******
* Init event handlers
******/
ColPicker.prototype.initHandlers = function(){
var picker = this;
this.picker.delegate('path[data-color]', 'click', function(e){
var $button = $(this);
picker.rgb = $button.attr('data-color');
if (picker.rgb === 'none') {
picker.opacity = '';
}
picker.color = picker.rgb + picker.opacity;
picker.initSelected();
picker.setColor();
picker.setPickerTransCol();
});
this.picker.delegate('[data-opacity]', 'click', function(e){
var $button = $(this);
picker.opacity = $button.attr('data-opacity');
if (picker.rgb !== 'none') {
picker.color = picker.rgb + picker.opacity;
} else {
picker.color = 'none';
}
picker.initSelected();
picker.setColor();
picker.setPickerTransCol();
});
this.place.bind('change', function(e){
picker.getColor();
picker.initSelected();
});
this.preview.filter('.colpickertool-hidebutton').bind('click', function(e){
picker.picker.toggleClass('colpickertool-hidden');
});
}
/******
* Find available id for the tool.
******/
ColPicker.prototype.genId = function(){
var i = 0;
while ($('#colorpickertool-'+i).length > 0){
i++;
}
return 'colorpickertool-'+i;
}
/******
* Hex to rgba
******/
ColPicker.prototype.hex2rgba = function(hex){
hex = hex + '#ffffffff'.slice(hex.length);
var rgb = hex.substr(1,6);
var alpha = hex.substr(7,2) || 'ff';
var num = parseInt(rgb, 16);
var r = (num >> 16) % 256;
var g = (num >> 8) % 256;
var b = num % 256;
var a = parseInt(alpha, 16) / 255;
return [r, g, b, a];
}
/******
* Named colors
******/
ColPicker.prototype.colornames = {
'black': '#000000',
'white': '#ffffff',
'red' : '#ff0000',
'green': '#00ff00',
'blue' : '#0000ff',
'yellow': '#ffff00',
'orange': '#ff6600',
'darkred': '#aa0000',
'darkgreen': '#00aa00',
'darkblue': '#0000aa',
'navy': '#000080',
'navyblue': '#000080',
'sky': '#87ceeb',
'skyblue': '#87ceeb',
'steel': '#4682b4',
'steelblue': '#4682b4',
'royal': '#4169e1',
'royalblue': '#4169e1',
'aqua': '#00ffff',
'cyan': '#00ffff',
'magenta': '#ff00ff',
'fuchsia': '#ff00ff',
'brown': '#a52a2a',
'chocolate': '#d2691e',
'pink': '#ffc0cb',
'lime': '#32cd32',
'olive': '#6b8e23',
'silver': '#c0c0c0',
'gray': '#808080',
'none' : 'none'
}
/******
* Some strings (css, svg)
******/
ColPicker.strings = {
css: [
'.colpickertool {background-color: transparent;}',
'.colpickertool-preview {display: block; height: 1.5em; border: 1px solid black; vertical-align: middle; margin: 0.2em; background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+CjxyZWN0IHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0iI2ZmZiI+PC9yZWN0Pgo8cmVjdCB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiNjY2MiPjwvcmVjdD4KPHJlY3QgeD0iMTAiIHk9IjEwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiNjY2MiPjwvcmVjdD4KPC9zdmc+");}',
'.colpickertool-preview .colorpreview {display: block; height: 100%;}',
'.colpickertool-preview .colpickertool-hidebutton {cursor: pointer}',
'.colpickertool-hidden {display: none;}',
'.colpickertool svg {width: 100%; height: auto;}',
'.colpickertool svg path.color-grayscale {stroke: black; stroke-width: 1}',
'.colpickertool svg path[data-color]:hover {cursor: pointer;}',
'.colpickertool svg rect[data-opacity]:hover {cursor: pointer;}',
'.colpickertool svg path.color-dark:hover {stroke-width: 2; stroke: white;}',
'.colpickertool svg path.color-light:hover {stroke-width: 2; stroke: white;}',
'.colpickertool svg path[data-selected-color="true"], .colpickertool svg rect[data-selected-opacity="true"] {stroke: black; stroke-width: 3; stroke-opacity: 1;}',
'.colpickertool svg path.color-grayscale[data-selected-color="true"] {stroke: red;}',
'input.colpicker-input {max-width: 100%; width: 100%; font-family: monospace; -moz-box-sizing: border-box; box-sizing: border-box;}'
].join('\n'),
svg: [
' <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="220" height="110" viewbox="-15 -5 230 110" class="colorpicker">',
' <path class="color-dark" transform="translate(12 14)" data-color="#aa0000" stroke="#aa0000" style="fill: #aa0000;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(36 14)" data-color="#aa4400" stroke="#aa4400" style="fill: #aa4400;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(60 14)" data-color="#ffcc00" stroke="#ffcc00" style="fill: #ffcc00;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(84 14)" data-color="#00aa00" stroke="#00aa00" style="fill: #00aa00;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(108 14)" data-color="#0000ff" stroke="#0000ff" style="fill: #0000ff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(132 14)" data-color="#660080" stroke="#660080" style="fill: #660080;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(156 14)" data-color="#aa0044" stroke="#aa0044" style="fill: #aa0044;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
////////
' <path class="color-dark" transform="translate(24 34)" data-color="#ff0000" stroke="#ff0000" style="fill: #ff0000;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(48 34)" data-color="#ff6600" stroke="#ff6600" style="fill: #ff6600;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(72 34)" data-color="#ffff00" stroke="#ffff00" style="fill: #ffff00;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(96 34)" data-color="#00ff00" stroke="#00ff00" style="fill: #00ff00;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(120 34)" data-color="#0066ff" stroke="#0066ff" style="fill: #0066ff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-dark" transform="translate(144 34)" data-color="#aa0088" stroke="#aa0088" style="fill: #aa0088;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
///////
' <path class="color-light" transform="translate(12 54)" data-color="#ff8080" stroke="#ff8080" style="fill: #ff8080;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(36 54)" data-color="#ff9955" stroke="#ff9955" style="fill: #ff9955;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(60 54)" data-color="#ffdd55" stroke="#ffdd55" style="fill: #ffdd55;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(84 54)" data-color="#bcd35f" stroke="#bcd35f" style="fill: #bcd35f;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(108 54)" data-color="#80e5ff" stroke="#80e5ff" style="fill: #80e5ff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(132 54)" data-color="#ccaaff" stroke="#ccaaff" style="fill: #ccaaff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-light" transform="translate(156 54)" data-color="#ffaaee" stroke="#ffaaee" style="fill: #ffaaee;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
////////
' <path class="color-none color-dark" transform="translate(0 85)" data-color="none" stroke="#000000" style="fill: #ffffff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z m5 0 l12 12 m-12 0 l12 -12" />',
' <path class="color-grayscale color-dark" transform="translate(24 85)" data-color="#000000" stroke="#000000" style="fill: #000000;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(48 85)" data-color="#333333" stroke="#333333" style="fill: #333333;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(72 85)" data-color="#4d4d4d" stroke="#4d4d4d" style="fill: #4d4d4d;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(96 85)" data-color="#808080" stroke="#808080" style="fill: #808080;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(120 85)" data-color="#999999" stroke="#999999" style="fill: #999999;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(144 85)" data-color="#cccccc" stroke="#cccccc" style="fill: #cccccc;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
' <path class="color-grayscale color-light" transform="translate(168 85)" data-color="#ffffff" stroke="#555555" style="fill: #ffffff;" stroke-width="2" d="M-11 -6 l11 -6 l11 6 l0 12 l-11 6 l-11 -6z" />',
////////
' <g class="color-transparent" transform="translate(190 -2)" fill="black">',
' <rect x="0" y="0" width="20" height="105" style="fill: transparent; stroke: black; stroke-width: 1px;" />',
' <rect x="0" y="0" width="20" height="15" fill-opacity="1" data-opacity="ff" />',
' <rect x="0" y="15" width="20" height="15" fill-opacity="0.83" data-opacity="d4" />',
' <rect x="0" y="30" width="20" height="15" fill-opacity="0.67" data-opacity="aa" />',
' <rect x="0" y="45" width="20" height="15" fill-opacity="0.5" data-opacity="80" />',
' <rect x="0" y="60" width="20" height="15" fill-opacity="0.33" data-opacity="55" />',
' <rect x="0" y="75" width="20" height="15" fill-opacity="0.167" data-opacity="2b" />',
' <rect x="0" y="90" width="20" height="15" fill-opacity="0" data-opacity="00" />',
' </g>',
' </svg>'].join('\n')
}
}
})(jQuery);
//}}}
//{{{
config.macros.contenttabs = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if(params.length>0){
var tabid = 'ebooktab-'+jQuery(place).parent().find('.ebooktabs').length;
var tabelementbox = jQuery(place).append('<div class="ebooktabs" id="'+tabid+'"></div>').find('#'+tabid);
var tablist = tabelementbox.append('<ul></ul>').find('ul');
for(var i=0;i<(params.length/2);i++){
tablist.append('<li><a href="#'+tabid+'-tabs-'+i+'">'+(i+1)+"."+(params[2*i]?params[2*i]:"")+'</a></li>');
tabelementbox.append('<div id="'+tabid+'-tabs-'+i+'"></div>');
wikify(params[2*i+1].replace(/\\/g,''),tabelementbox.find('#'+tabid+'-tabs-'+i)[0],null,tiddler);
}
tabelementbox.tabs();
}
}
}
//}}}
/***
|''Name:''|courseComment.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Commenting from E-Math-book|
|''Version:''|1.0|
|''Date:''|November 2, 2012|
|''Source:''||
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130830.1549 ''fix''
* Correct url for sending and version information
<<<
!!!!!Code
***/
//{{{
Emathbook.pageComment = function(){
/******************************************************
* Tool for creating a comment
******************************************************/
var commentto = EbookPages[0].ebook.tocdict[EbookPages[0].currentpage].content;
var tiddlerName = commentto + '_comment_'+config.options.txtUserName;
var commenttext = '';
var commentdata = {};
var dialogbox;
if (store.tiddlerExists(tiddlerName)){
commenttext = store.getTiddlerText(tiddlerName).replace(/\n*<data>.*<\/data>\n*/,'');
commentdata = DataTiddler.getData(tiddlerName, 'pagecomments', {});
}
var ctypes = ['content','system','layout'];
for (var i = 0; i<ctypes.length; i++){
commentdata[ctypes[i]] = commentdata[ctypes[i]] || {'text':'','date':''};
}
openDialog('pagecomment', EbookDictionary.localize('comment this page'), ['chk_sendserver','commenttype','pagecomment']); // Localization
dialogbox.dialog('option','width',jQuery('body').width() /2);
dialogbox.dialog('option','position',['right','center']);
dialogbox.find('.pagecomment').append('<h1>'+EbookDictionary.localize('my comment')+':</h1><textarea id="mypagecomment" name="mypagecomment" style="width: 100%;height:20em;">'+commenttext+'</textarea>');
dialogbox.find('.chk_sendserver').css('display','none').append('<label for="chksendcomment">Send comment to the server</label><input id="chksendcomment" checked="checked" type="checkbox" />');
var selectedtype = 'general';
dialogbox.find('.commenttype').append('<h2>'+EbookDictionary.localize('comment type')+'</h2><input name="commenttype" type="radio" value="general" checked="checked">'+EbookDictionary.localize('general')+'</input><input name="commenttype" type="radio" value="content">'+EbookDictionary.localize('content')+'</input><input name="commenttype" type="radio" value="system">'+EbookDictionary.localize('system')+'</input><input name="commenttype" type="radio" value="layout">'+EbookDictionary.localize('layout')+'</input>')
.find('input[name="commenttype"]').click(function(){
if (selectedtype == 'general'){
commenttext = dialogbox.find('.pagecomment textarea#mypagecomment').val();
} else {
commentdata[selectedtype].text = dialogbox.find('.pagecomment textarea#mypagecomment').val();
commentdata[selectedtype].date = (new Date()).toString();
}
selectedtype = jQuery(this).val();
if (selectedtype == 'general'){
dialogbox.find('.pagecomment textarea#mypagecomment').val(commenttext);
} else {
dialogbox.find('.pagecomment textarea#mypagecomment').val(commentdata[selectedtype].text);
}
});
function save(){
dialogbox.find('.commenttype input[name="commenttype"]:checked').click();
var allcommentdata = {
'content': commenttext + '\n<data>{"pagecomments":' + JSON.stringify(commentdata) + '}</data>',
'tags': ['pagecomment']
}
saveTiddler(tiddlerName, allcommentdata.content, allcommentdata.tags, '',null, {"commentto": commentto});
if (dialogbox.find('#chksendcomment').attr('checked')){
Emathbook.sendCoursePageComment(tiddlerName);
}
refreshElements(jQuery('#pageTwo')[0], ['ebookcomments']);
return true;
}
function saveTiddler(tiddlerName, content, tags, ebooktitle, container, fields) {
var tiddler;
if (store.tiddlerExists(tiddlerName)) {
tiddler = store.getTiddler(tiddlerName);
} else {
tiddler = store.createTiddler(tiddlerName);
}
for (var i = 0; i < tags.length; i++) {
tiddler.tags.pushUnique(tags[i]);
}
fields = fields || {};
fields.ebooktitle = ebooktitle;
if (container) {
fields.container = container;
}
var now = new Date;
tiddler.set(tiddler.title, content, config.options.txtUserName, now, tiddler.tags, tiddler.created, fields, config.options.txtUserName);
return tiddlerName;
}
function openDialog(dialogid, title, elements) {
jQuery("body").append("<div id=\"authordialog_" + dialogid + "\"></div>");
dialogbox = jQuery("#authordialog_" + dialogid);
for (var i = 0; i < elements.length; i++) {
dialogbox.append("<div class=\"dialogelement " + elements[i] + "\"></div>");
}
var butt = {};
butt[EbookDictionary.localize('cancel')] = function () {
jQuery(this).dialog("destroy").remove();
jQuery("#actionButtons .actionmenu.menuopen button.actionmenuitem_Cancel").click();
jQuery("#actionButtons .actionmenu.menuopen button.actionmenubutton").click();
};
butt[EbookDictionary.localize('save')] = function () {
if (save()) {
jQuery(this).dialog("destroy").remove();
}
};
dialogbox.dialog({
buttons: butt,
width: 800,
height: 600,
autoOpen: true,
title: title,
close: function () {
jQuery(this).dialog("close").dialog("destroy").remove();
}
});
}
return tiddlerName;
}
Emathbook.sendCoursePageComment = function(tiddlerName, upUrl, version){
var updateurl = upUrl ;
var tdata = store.getSaver().externalizeTiddler(store, store.getTiddler(tiddlerName));
var data = {
'sendPageComment': 'send',
'username': config.options.txtUserName,
'userkey': config.options.txtUserKey,
'courseid': Emathbook.options.pages[0].courseid,
'tiddlerName': tiddlerName,
'tiddlerData': tdata,
'bookId': EbookPages[0].ebook.bookid,
'version': version || '2013'
};
var response = jQuery.postCORS(updateurl, data, function(repdata){
if (repdata == 'Ok'){
alert("Your comment has been sent."); //localize
} else {
alert("Something went wrong. Try again later"); //localize
}
});
}
//}}}
<<showData>>
<data>{"courseid":"","coursename":"","coursebooks":[],"updateURL":"http://emath.utu.fi/Emath","coursekey":"","coursedata":{},"lang":""}</data>
!usage
{{{[img[downpage.png]]}}}
[img[downpage.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANgAAADYABpllopAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFFSURBVDiNrZSxSsNQFIa/E1Ko4JN0LSURBRF066QE2oeQCh0KLi6dMgnO0gcoujkpiKCYlrp17Japc7FCWnIcDFWaNElr/+nec/773f/C4Yqqsk0ZW6UBJsB9zz4KVQ7/AzJEX04t79kECIxwZIbGA7CzIe8rMMJbiJ5cq/R9VNyN46m4tUrfXwABioWZK+CvyxLwi4XZIswCWC0Ppoi21k4n2qqWB9Pf7dLYdHv2q8B+HpbCm2N5B39rSWPT+PHm4dFYLsaAjuV9AJ0cwE7kTQcCzOASmKTAJpEnpkRg3fLGiLZX4kTbdcsb5wYC6O7nNTBKaI2iXqJWAp3SMFCVZuwilaZTGgarzsXGZlndnv0ocAyg8ORY3kmaP/O3MYzwApgD82idqsyEAHfe3g3Amf1+nuU1M2lAqHKVxwc5E66jrf/Y37kBb4rnY5seAAAAAElFTkSuQmCC
//{{{
elementFunctions.getWikibookelement = function(inputdata,iseditable){
return '<<tiddler [['+inputdata + ']]>>\n'
}
elementFunctions.addbookelement = function(elementSet, posindex, copyfrom){
var elementdata = {"type":"bookelement","data": copyfrom};
var element = new EbElement(elementdata, false);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"bookelement","addFunction":"addbookelement"}}</data>
//{{{
elementFunctions.getWikibookpage = function(inputdata,iseditable){
return '<<tiddler [['+inputdata + ']]>>\n'
}
elementFunctions.addbookpage = function(elementSet, posindex, copyfrom){
var elementdata = {"type":"bookpage","data": copyfrom};
var element = new EbElement(elementdata, false);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"bookpage","addFunction":"addbookpage"}}</data>
//{{{
elementFunctions.getWikisderivation = function(inputdata,iseditable){
return '<<qedderiv [['+inputdata+']] savehere>>\n';
}
elementFunctions.addDerivation = function(elementSet, posindex, copyfrom){
var derivations = DataTiddler.getData(elementSet.tiddlerName, 'derivations', {});
var index = 0;
while (typeof(derivations['sderiv'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"sderivation","data": 'sderiv'+index};
if (typeof(copyfrom) === 'undefined'){
derivations['sderiv'+index] = {"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":""}],"relation":[],"motivation":[]};
} else {
var rex = new RegExp(copyfrom);
derivations['sderiv'+index] = JSON.parse(JSON.stringify(derivations[copyfrom]).replace(rex, 'sderiv'+index));
var rex2 = new RegExp('^'+copyfrom);
for (var der in derivations){
if (rex2.test(der)){
var suffix = der.slice(('sderiv'+index).length);
derivations['sderiv'+index+suffix] = JSON.parse(JSON.stringify(derivations[der]).replace(rex, 'sderiv'+index));
}
}
}
DataTiddler.setData(elementSet.tiddlerName, 'derivations', derivations);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"sderivation","addFunction":"addDerivation","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><circle cx=\"6\" cy=\"4\" r=\"2\" /><line stroke=\"black\" x1=\"15\" y1=\"4\" x2=\"30\" y2=\"4\" /><path stroke=\"black\" stroke-width=\"1\" fill=\"none\" d=\"M1 15 l3 -3 l0 1 l4 0 l0 -1 l3 3 l-3 3 l0 -1 l-4 0 l0 1z\" /><path stroke=\"black\" stroke-width=\"1\" fill=\"none\" d=\"M17 9 l-1 1 l0 3 l-2 2 l2 2 l0 3 l1 1\" /><line stroke=\"black\" x1=\"18\" y1=\"15\" x2=\"25\" y2=\"15\" /><path stroke=\"black\" stroke-width=\"1\" fill=\"none\" d=\"M26 9 l1 1 l0 3 l2 2 l-2 2 l0 3 l-1 1\" /><line stroke=\"black\" x1=\"15\" y1=\"26\" x2=\"30\" y2=\"26\" /></svg>"}}</data>
//{{{
elementFunctions.getWikiemfuncgraph= function(inputdata,iseditable){
return '<<emathfuncgraph [['+inputdata+']]'+iseditable+'>>\n';
}
elementFunctions.addEmathfuncgraph = function(elementSet, posindex, copyfrom){
var emfuncgraphs = DataTiddler.getData(elementSet.tiddlerName, 'emathfuncgraph', {});
var index = 0;
while (typeof(emfuncgraphs['emfg'+index]) !== 'undefined'){
index++;
}
var elementdata = {"type":"emfuncgraph","data": 'emfg'+index};
if (typeof(copyfrom) === 'undefined'){
emfuncgraphs['emfg'+index] = {editable: true};
} else {
emfuncgraphs['emfg'+index] = jQuery.extend(emfuncgraphs[copyfrom], {});
}
DataTiddler.setData(elementSet.tiddlerName, 'emathfuncgraph', emfuncgraphs);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"funcgraph","addFunction":"addEmathfuncgraph","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><path stroke=\"#666\" stroke-width=\"1\" fill=\"none\" d=\"M15 30 L15 0 L14 2 L16 2 L15 0\" /><path stroke=\"#666\" stroke-width=\"1\" fill=\"none\" d=\"M0 15 L30 15 L27 14 L27 16 L30 15\" /><path stroke=\"red\" stroke-width=\"2\" fill=\"none\" d=\"M5 25 Q10 0 15 15 Q20 30 25 5\" /></svg>"}}</data>
//{{{
elementFunctions.getWikigeoeditor= function(inputdata,iseditable){
return '<<geoedit2 [['+inputdata+']]'+iseditable+'>>\n';
}
elementFunctions.addEmathgeoeditor= function(elementSet, posindex, copyfrom){
var geoeditors = DataTiddler.getData(elementSet.tiddlerName, 'Geoeditors', {});
var index = 0;
while (typeof(geoeditors['geoeditor'+index]) !== 'undefined'){
index++;
}
var elementdata = {"type":"geoeditor","data": 'geoeditor'+index};
if (typeof(copyfrom) === 'undefined'){
geoeditors['geoeditor'+index] = {editable: true};
} else {
geoeditors['geoeditor'+index] = jQuery.extend(geoeditors[copyfrom], {});
}
DataTiddler.setData(elementSet.tiddlerName, 'Geoeditors', geoeditors);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"geoeditor","addFunction":"addEmathgeoeditor","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\" class=\"geoedit-icon geoedit-object-line\"><circle style=\"stroke: #0a0; stroke-width: 2; fill: none; stroke-dasharray: 2,2;\" cx=\"20\" cy=\"20\" r=\"10\" /><rect style=\"stroke: blue; fill: none;\" x=\"3\" y=\"5\" width=\"14\" height=\"10\" /><circle style=\"stroke: none; fill: red;\" cx=\"3\" cy=\"5\" r=\"2\" /><circle style=\"stroke: none; fill: red;\" cx=\"17\" cy=\"5\" r=\"2\" /><circle style=\"stroke: none; fill: red;\" cx=\"17\" cy=\"15\" r=\"2\" /><circle style=\"stroke: none; fill: red;\" cx=\"3\" cy=\"15\" r=\"2\" /><line style=\"fill: none; stroke: blue; stroke-width: 1.7\" x1=\"20\" y1=\"20\" x2=\"5\" y2=\"23\"/><path style=\"stroke: none; fill: blue;\" d=\"M6 23 l0 -3 l-4 3.5 l5.2 2.3z\" /></svg>"}}</data>
//{{{
elementFunctions.getWikiimage = function(inputdata,iseditable){
return '<<ownimage [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addImage = function(elementSet, index, copyfrom){
var imagedata = DataTiddler.getData(elementSet.tiddlerName, 'imagedata', {});
var index = 0;
while (typeof(imagedata['imagedata'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"image","data": 'imagedata'+index};
if (typeof(copyfrom) === 'undefined'){
imagedata['imagedata'+index] = '';
} else {
imagedata['imagedata'+index] = imagedata[copyfrom];
}
DataTiddler.setData(elementSet.tiddlerName, 'imagedata', imagedata);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, index);
elementSet.save();
}
config.macros.ownimage = {
/**********************************************
* Insert Mathquill-textbox. The content will
* be saved in this tiddler with DataTiddler-plugin
* on each focusout.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
alert('NOT IMPLEMENTED yet')
/*
var textid = params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksoltext mathtext_'+textid+'{';
var solclassend = '}}}\n';
var textdata = DataTiddler.getData(tiddler, 'mathtext', {});
var text = textdata[textid] || '';
if (iseditable){
var result = solclassstart + '<html><span class="mathquill-textbox" latex="'+text+'"></span></html>' + solclassend;
} else {
var result = solclassstart + '{{solutiontext{'+text+'}}}' + solclassend;
}
wikify(result, place, null, tiddler);
var mathelement = jQuery(place).find('.mathquill-textbox:not(.mathquill-rendered-math):last');
var latex = mathelement.attr('latex');
mathelement.empty().append(latex);
var edata = {'tiddler': tiddler.title, 'textid': textid};
if (iseditable){
mathelement.mathquill('textbox');
} else {
mathelement.mathquill('embedded-latex');
}
mathelement.focusout(edata, function(e){
var latex = jQuery(this).mathquill('latex');
var textid = e.data.textid;
var tiddler = e.data.tiddler;
var mathdata = DataTiddler.getData(tiddler, 'mathtext', {});
mathdata[textid] = latex;
DataTiddler.setData(tiddler, 'mathtext', mathdata);
});
*/
}
}
//}}}
<data>{"addElement":{"elementType":"image","addFunction":"addImage"}}</data>
//{{{
elementFunctions.getWikimultichoise = function(inputdata,iseditable){
return '<<multichoiseQuestion [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addmultichoise = function(elementSet){
var multichoiseData = DataTiddler.getData(elementSet.tiddlerName, 'multichoiseData', {});
var index = 0;
while (typeof(wikiTextdata['multichoiseData'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"multichoise","data": 'multichoiseData'+index};
multichoiseData['multichoiseData'+index] = '';
//No saving while adding new
var autosaveStatus =config.options.chkAutoSave;
config.options.chkAutoSave=false;
DataTiddler.setData(elementSet.tiddlerName, 'multichoiseData', multichoiseData);
config.options.chkAutoSave = autosaveStatus;
var element = new EbElement(elementdata, true);
elementSet.addElement(element);
elementSet.save();
}
config.macros.multichoiseQuestion = {
/**********************************************
* MultichoiseQuestion
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var notTeacher = typeof(Teachertool) !== "function";
var multichoiseid = params[0];
var multiTiddler = tiddler.title+'_'+params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksolmultichoise multichoise_'+multichoiseid+'{';
var solclassend = '}}}\n';
var multichoisedata = DataTiddler.getData(tiddler, 'multichoiseData', {});
var thisData = multichoisedata[multichoiseid] || {"question":"","correct":"","wrong":[""]};
qustion_html="{{question_text multichoise{"+thisData.question+"}}}";
var choises=[];
wikify(solclassstart + qustion_html + solclassend, place, null, tiddler);
$tiddler.find('.question_text').after('<ul class="multichoiseChoises multi'+multiTiddler+'"></ul>');
var solutions = store.reverseLookup('solutionto',multiTiddler, true);
if (solutions.length){
var clicked=DataTiddler.getDataObject(solutions[0]);
}else{
var clicked={};
}
choises.push('<li class="choise_1"><span class="multimark">'+((typeof(clicked['choise_1'])=='undefined' && notTeacher) ? '<input type="radio" name="'+multiTiddler+'" value="choise_1">' : '<span class="multicorrect"><span>✓</span></span>')+'</span><span class="choiseText"></span></li>');
for (var i=0;i<thisData['wrong'].length;i++){
choises.push('<li class="choise_'+(i+2)+'"><span class="multimark">'+((typeof(clicked['choise_'+(i+2)])=='undefined' && notTeacher) ? '<input type="radio" name="'+multiTiddler+'" value="choise_'+(i+2)+'">':'<span class="multiwrong"><span>✗</span></span>')+'</span><span class="choiseText"></span></li>');
}
var $multichoiseList = $tiddler.find('.multichoiseChoises.multi'+multiTiddler);
if(notTeacher){
choises.sort(function(a,b){return (Math.random()-0.5)});
choises.sort(function(a,b){return (Math.random()-0.5)});
choises.sort(function(a,b){return (Math.random()-0.5)});
choises.sort(function(a,b){return (Math.random()-0.5)});
}
for(var i=0;i<choises.length;i++){
$multichoiseList.append(choises[i]);
}
$multichoiseList.addClass((typeof(clicked['choise_1'])=='undefined' && notTeacher ? '':'solved'));
wikify(thisData['correct'],$multichoiseList.find('li.choise_1 span.choiseText')[0]);
for (var i=0;i<thisData['wrong'].length;i++){
wikify(thisData['wrong'][i],$multichoiseList.find('li.choise_'+(i+2)+' span.choiseText')[0]);
}
$multichoiseList.find('li span.choiseText').mathquill();
if (!$multichoiseList.hasClass('solved')){
$multichoiseList.find('input[type="radio"]').click(function(){
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var $inputElem = jQuery(this);
if (!solutions.length){
var lastSolution = store.getTiddler(Emathbook.createSolution(multiTiddler,""));
solutions.push(lastSolution);
}else{
var lastSolution = solutions[0];
}
DataTiddler.setData(lastSolution,$inputElem.val(),"clicked");
if($inputElem.val()=='choise_1'){
$inputElem.after('<span class="multicorrect"><span>✓</span></span>');
$multichoiseList.addClass('solved');
DataTiddler.setData(lastSolution,"multichoise","solved");
var sendData = {'type':'5','tiddlerName':lastSolution.title,'isPublic':1};
Emathbook.getCourseUpdatesSilent(sendData);
}else{
$inputElem.after('<span class="multiwrong"><span>✗</span></span>');
}
$inputElem.remove();
config.options.chkAutoSave = autosaveoption;
});
}
if(iseditable){//focusout().blur().
$tiddler.find('.question_text').addClass('editQuestion').empty().mathquill('textbox').mathquill('latex',thisData.question).focusout().blur().focusout(function(){
thisData.question = jQuery(this).mathquill('latex');
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
multichoisedata[multichoiseid] = thisData;
DataTiddler.setData(tiddler,'multichoiseData',multichoisedata);
config.options.chkAutoSave = autosaveoption;
});
$multichoiseList.find('li span.choiseText').mathquill('revert').mathquill('editable').focusout(function(){
var latexText = jQuery(this).mathquill('latex');
var liIndex = parseInt(jQuery(this).parent().attr('class').match('choise_([0-9+])')[1]);
if(liIndex === 1){
thisData.correct = latexText;
}else{
thisData.wrong[liIndex-2] = latexText;
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
multichoisedata[multichoiseid] = thisData;
DataTiddler.setData(tiddler,'multichoiseData',multichoisedata);
config.options.chkAutoSave = autosaveoption;
});
$multichoiseList.find('li:not(.choise_1,.choise_2) span.choiseText').after('<span class="removemultichoiseelem"><a href="javascript:;">'+Ebooksvgicons['trashcan']+'</a></span>');
$multichoiseList.find('.removemultichoiseelem a').click( function(){
var currentLi = jQuery(this).parent().parent();
var liIndex = parseInt(currentLi.attr('class').match('choise_([0-9+])')[1]);
currentLi.addClass('removeMe');
var multiLi = $multichoiseList.find('li:not(.removeMe)');
for(var i=liIndex-1;i<multiLi.length;i++){
multiLi[i].attr('class','choise_'+(i+1));
}
thisData.wrong.splice(liIndex-2,1);
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
multichoisedata[multichoiseid] = thisData;
DataTiddler.setData(tiddler,'multichoiseData',multichoisedata);
config.options.chkAutoSave = autosaveoption;
currentLi.remove();
});
$multichoiseList.after('<button class="addMultiwrong">'+EbookDictionary.localize('Add incorrect')+'</button>').parent().find('button.addMultiwrong').click(function(){
thisData.wrong.push('');
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
multichoisedata[multichoiseid] = thisData;
DataTiddler.setData(tiddler,'multichoiseData',multichoisedata);
config.options.chkAutoSave = autosaveoption;
$tiddler.empty();
config.macros.multichoiseQuestion.handler(place, macroName, params, wikifier, paramString, tiddler);
}).button();
$tiddler.addClass('notrashcan');
}
}
}
//}}}
<data>{"addElement":{"elementType":"multichoise","addFunction":"addmultichoise"}}</data>
//{{{
elementFunctions.getWikisdshuffle = function(inputdata,iseditable){
return '<<sdshuffleQuestion [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addsdshuffle = function(elementSet){
var sdshuffleData = DataTiddler.getData(elementSet.tiddlerName, 'sdshuffleData', {});
var index = 0;
while (typeof(wikiTextdata['sdshuffleData'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"sdshuffle","data": 'sdshuffleData'+index};
sdshuffleData['sdshuffleData'+index] = '';
//No saving while adding new
var autosaveStatus =config.options.chkAutoSave;
config.options.chkAutoSave=false;
DataTiddler.setData(elementSet.tiddlerName, 'sdshuffleData', sdshuffleData);
config.options.chkAutoSave = autosaveStatus;
var element = new EbElement(elementdata, true);
elementSet.addElement(element);
elementSet.save();
}
config.macros.sdshuffleQuestion = {
/**********************************************
* sdshuffleQuestion
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var notTeacher = typeof(Teachertool) !== "function";
var sdshuffleid = params[0];
var shuffleTiddler = tiddler.title+'_'+params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksolsdshuffle sdshuffle_'+sdshuffleid+'{\n!!'+EbookDictionary.localize('ordersd')+'\n';
var solclassend = '}}}\n';
var qustion_html = '';
var sdshuffledata = DataTiddler.getData(tiddler, 'sdshuffleData', {});
var thisData = sdshuffledata[sdshuffleid] || {"derivations":"","answers":[]};
wikify(solclassstart+'<<qedderiv '+sdshuffleid+' savehere>>'+solclassend, place, null, tiddler);
if(notTeacher){
var solutions = store.reverseLookup('solutionto',shuffleTiddler, true);
if(solutions.length){
$tiddler.addClass('sdInOrder');
}else{
var tableRows = $tiddler.find('.sdtable tr');
for (var i=0;i<tableRows.length;i++){
tableRows.eq(i).attr('order',i);
}
var allDerivations = $tiddler.find('.sdtable').children('tbody');
allDerivations.addClass(shuffleTiddler+'shuffle');
for(var i=0;i<allDerivations.length;i++){
allDerivations.eq(i).children('tr').shuffle();
allDerivations.eq(i).sortable().disableSelection();
}
$tiddler.find('.'+shuffleTiddler+'shuffle').bind( "sortupdate", function(event, ui) {
tableRows = $tiddler.find('.sdtable tr');
for(var i=0;i<tableRows.length;i++){
if(tableRows.eq(i).attr('order') != i){break};
if(i==tableRows.length-1){
$tiddler.find('.'+shuffleTiddler+'shuffle').sortable('destroy');
$tiddler.addClass('sdInOrder');
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var lastSolution=Emathbook.createSolution(shuffleTiddler,"");
DataTiddler.setData(lastSolution,'solved','solved');
config.options.chkAutoSave = autosaveoption;
}
}
});
}
}else{
if(iseditable){
$tiddler.addClass('notrashcan');
$tiddler.find('.command_qededit').click();
$tiddler.find('.command_qedclose').remove();
}
}
}
}
//}}}
<data>{"addElement":{"elementType":"sdshuffle","addFunction":"addsdshuffle"}}</data>
//{{{
elementFunctions.getWikishortanswer = function(inputdata,iseditable){
return '<<shortanswerQuestion [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addshortanswer = function(elementSet){
var shortanswerData = DataTiddler.getData(elementSet.tiddlerName, 'shortanswerData', {});
var index = 0;
while (typeof(wikiTextdata['shortanswerData'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"shortanswer","data": 'shortanswerData'+index};
shortanswerData['shortanswerData'+index] = '';
//No saving while adding new
var autosaveStatus =config.options.chkAutoSave;
config.options.chkAutoSave=false;
DataTiddler.setData(elementSet.tiddlerName, 'shortanswerData', shortanswerData);
config.options.chkAutoSave = autosaveStatus;
var element = new EbElement(elementdata, true);
elementSet.addElement(element);
elementSet.save();
}
config.macros.shortanswerQuestion = {
/**********************************************
* shortanswerQuestion
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var notTeacher = typeof(Teachertool) !== "function";
var shortanswerid = params[0];
var shortTiddler = tiddler.title+'_'+params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksolshortanswer shortanswer_'+shortanswerid+'{';
var solclassend = '}}}\n';
var qustion_html = '';
var shortanswerdata = DataTiddler.getData(tiddler, 'shortanswerData', {});
var thisData = shortanswerdata[shortanswerid] || {"question":"","answers":[]};
if(iseditable){
var shortText = thisData.question;
for(var i=0;i<thisData.answers.length;i++){
shortText = shortText.replace('\\editable{}',thisData.answers[i]);
}
qustion_html="{{question_text shortanswer{"+shortText+"}}}";
}else{
qustion_html="{{question_text shortanswer{"+thisData.question+"}}}";
}
wikify(solclassstart + qustion_html + solclassend, place, null, tiddler);
if(iseditable){
var $question = $tiddler.find('.question_text');//.empty().mathquill('textbox').mathquill('latex',shortText);
var SAquestion = shortText;
var solutionsSpans= $question.find('.solution');
for(var j=0; j<solutionsSpans.length;j++){
var SAsolution = solutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
//SAquestion = SAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
$tiddler.find('.question_text').empty().mathquill('textbox').mathquill('latex',SAquestion).focusout(function(){
var modifiedSAquestion = jQuery(this).mathquill('latex');
var modifiedsolutionsSpans= jQuery(this).find('.solution');
var hasSolutions = true;
var SAsolutions = [];
for(var j=0; j<modifiedsolutionsSpans.length;j++){
var SAsolution = modifiedsolutionsSpans.eq(j).mathquill('latex');
SAsolution = (SAsolution.charAt(SAsolution.length-1)==" "? SAsolution.substring(0,SAsolution.length-1): SAsolution);
SAsolution = SAsolution.replace(/\ ([\+\-\}])/g,'$1');
SAsolutions.push(SAsolution);
if (SAsolution==""){ hasSolutions = false;}
// modifiedSAquestion = modifiedSAquestion.replace('\\solution{'+SAsolution+'}','\\solution{\\editable{}}');
}
if (hasSolutions){thisData.answers = SAsolutions;}else{thisData.answers = [];}
thisData.question = modifiedSAquestion;
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
shortanswerdata[shortanswerid] = thisData;
DataTiddler.setData(tiddler,'shortanswerData',shortanswerdata);
config.options.chkAutoSave = autosaveoption;
});
$tiddler.addClass('notrashcan');
}else{
$tiddler.find('.mathquill-embedded-latex.mathquill-rendered-math').attr('title','');
var solutions = store.reverseLookup('solutionto',shortTiddler, true);
var isSolved = 'not';
var editables = $tiddler.find('.question_text span.solution .mathquill-editable');
var answers = [];
if(solutions.length && notTeacher){
isSolved = DataTiddler.getData(solutions[0],'solved','not');
answers = DataTiddler.getData(solutions[0],'answers',[]);
}else{
for(var i=0;i<editables.length;i++){
answers.push("");
}
}
for(var i=0;i<editables.length;i++){
if (answers[i] != ""){
editables.eq(i).mathquill('latex',answers[i]);
}
}
if(notTeacher){
if (isSolved == "solved"){
editables.removeClass('mathquill-editable');
$tiddler.append('<span class="shortanswercorrect"><span>✓</span></span>');
}else{
editables.focusout(function(){
if(!solutions.length){
if( typeof(lastSolution)==="undefined"){
var lastSolution = store.getTiddler(Emathbook.createSolution(shortTiddler,""));
solutions.push(lastSolution);
}
}else{
var lastSolution = solutions[0];
}
var autosaveoption = config.options.chkAutoSave;
config.options.chkAutoSave = false;
var thisElement = jQuery(this);
answers[editables.index(thisElement)]=thisElement.mathquill('latex');
DataTiddler.setData(lastSolution,'answers',answers);
if(!!answers && !!thisData.answers && !(answers<thisData.answers || thisData.answers<answers)){
DataTiddler.setData(lastSolution,'solved','solved');
editables.removeClass('mathquill-editable');
$tiddler.append('<span class="shortanswercorrect"><span>✓</span></span>');
var sendData = {'type':'5','tiddlerName':lastSolution.title,'isPublic':1};
Emathbook.getCourseUpdatesSilent(sendData);
editables.unbind('focusout');
}
config.options.chkAutoSave = autosaveoption;
});
}
}else{
if(thisData.answers.length ==0){
$tiddler.addClass('noAllanswers');
}
for(var i=0;i<editables.length;i++){
if (thisData.answers[i] != ""){
editables.eq(i).mathquill('latex',thisData.answers[i]);
}
}
editables.removeClass('mathquill-editable');
}
}
}
}
//}}}
<data>{"addElement":{"elementType":"shortanswer","addFunction":"addshortanswer"}}</data>
//{{{
elementFunctions.getWikisignchart = function(inputdata,iseditable){
return '<<pssignchart [['+inputdata+']]'+iseditable+'>>\n';
}
elementFunctions.addPssignchart = function(elementSet, posindex, copyfrom){
var pssigncharts = DataTiddler.getData(elementSet.tiddlerName, 'signchart', {});
var index = 0;
while (typeof(pssigncharts['pssc'+index]) !== 'undefined'){
index++;
}
var elementdata = {"type":"signchart","data": 'pssc'+index};
if (typeof(copyfrom) === 'undefined'){
pssigncharts['pssc'+index] = {rows:[], total:{}, intervals:[], rootpoints:[], undefinedpoint: [], editable: true};
} else {
pssigncharts['pssc'+index] = jQuery.extend(pssigncharts[copyfrom], {});
}
DataTiddler.setData(elementSet.tiddlerName, 'signchart', pssigncharts);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"signchart","addFunction":"addPssignchart","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><line stroke=\"#666\" stroke-width=\"1\" x1=\"0\" y1=\"15\" x2=\"30\" y2=\"15\" /><line stroke=\"#666\" stroke-width=\"1\" x1=\"15\" y1=\"0\" x2=\"15\" y2=\"30\" /><line stroke=\"red\" stroke-width=\"2\" x1=\"7\" y1=\"2\" x2=\"7\" y2=\"12\" /><line stroke=\"red\" stroke-width=\"2\" x1=\"2\" y1=\"7\" x2=\"12\" y2=\"7\" /><line stroke=\"red\" stroke-width=\"2\" x1=\"22\" y1=\"17\" x2=\"22\" y2=\"27\" /><line stroke=\"red\" stroke-width=\"2\" x1=\"17\" y1=\"22\" x2=\"27\" y2=\"22\" /><line stroke=\"blue\" stroke-width=\"2\" x1=\"2\" y1=\"22\" x2=\"12\" y2=\"22\" /><line stroke=\"blue\" stroke-width=\"2\" x1=\"17\" y1=\"7\" x2=\"27\" y2=\"7\" /></svg>"}}</data>
//{{{
elementFunctions.getWikiemtable= function(inputdata,iseditable){
return '<<emathtable [['+inputdata+']]'+iseditable+'>>\n';
}
elementFunctions.addEmathtable = function(elementSet, posindex, copyfrom){
var emtables = DataTiddler.getData(elementSet.tiddlerName, 'emathtable', {});
var index = 0;
while (typeof(emtables['emtable'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"emtable","data": 'emtable'+index};
if (typeof(copyfrom) === 'undefined'){
emtables['emtable'+index] = {editable: true};
} else {
emtables['emtable'+index] = jQuery(emtables[copyfrom], {});
}
DataTiddler.setData(elementSet.tiddlerName, 'emathtable', emtables);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"table","addFunction":"addEmathtable","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><line stroke=\"#666\" stroke-width=\"1\" x1=\"0\" y1=\"15\" x2=\"30\" y2=\"15\" /><line stroke=\"#666\" stroke-width=\"1\" x1=\"15\" y1=\"0\" x2=\"15\" y2=\"30\" /><rect x=\"1\" y=\"1\" width=\"29\" height=\"29\" fill=\"none\" stroke=\"#666\" stroke-width=\"1\" /><text x=\"3\" y=\"12\" style=\"font-size: 12px\">A</text><text x=\"18\" y=\"12\" style=\"font-size: 12px\">B</text><text x=\"3\" y=\"27\" style=\"font-size: 12px\">1</text><text x=\"18\" y=\"27\" style=\"font-size: 12px\">2</text></svg>"}}</data>
//{{{
elementFunctions.getWikiteacherelement = function(inputdata,iseditable){
return '<<tiddler [['+inputdata + ']]>>\n'
}
elementFunctions.addteacherelement = function(elementSet, posindex, copyfrom){
var elementdata = {"type":"teacherelement","data": copyfrom};
var element = new EbElement(elementdata, false);
elementSet.addElement(element, posindex);
elementSet.save();
}
//}}}
<data>{"addElement":{"elementType":"teacherelement","addFunction":"addteacherelement"}}</data>
//{{{
elementFunctions.getWikitext = function(inputdata,iseditable){
return '<<solutiontext [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addText = function(elementSet, posindex, copyfrom){
var mathtext = DataTiddler.getData(elementSet.tiddlerName, 'mathtext', {});
var index = 0;
while (typeof(mathtext['mathtext'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"text","data": 'mathtext'+index};
if (typeof(copyfrom) === 'undefined'){
mathtext['mathtext'+index] = '';
} else {
mathtext['mathtext'+index] = mathtext[copyfrom];
}
DataTiddler.setData(elementSet.tiddlerName, 'mathtext', mathtext);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
config.macros.solutiontext = {
/**********************************************
* Insert Mathquill-textbox. The content will
* be saved in this tiddler with DataTiddler-plugin
* on each focusout.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var textid = params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksoltext mathtext_'+textid+'{';
var solclassend = '}}}\n';
var textdata = DataTiddler.getData(tiddler, 'mathtext', {});
var text = textdata[textid] || '';
if (iseditable){
var result = solclassstart + '<html><span class="mathquill-textbox" latex="'+text+'"></span></html>' + solclassend;
} else {
var result = solclassstart + '{{solutiontext{'+text+'}}}' + solclassend;
}
wikify(result, place, null, tiddler);
var mathelement = jQuery(place).find('.mathquill-textbox:not(.mathquill-rendered-math):last');
var latex = mathelement.attr('latex');
mathelement.empty().append(latex);
var edata = {'tiddler': tiddler.title, 'textid': textid};
if (iseditable){
mathelement.mathquill('textbox');
} else {
mathelement.mathquill('embedded-latex');
}
mathelement.focusout(edata, function(e){
var latex = jQuery(this).mathquill('latex');
var textid = e.data.textid;
var tiddler = e.data.tiddler;
var mathdata = DataTiddler.getData(tiddler, 'mathtext', {});
mathdata[textid] = latex;
DataTiddler.setData(tiddler, 'mathtext', mathdata);
});
}
}
//}}}
<data>{"addElement":{"elementType":"text","addFunction":"addText","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><path fill=\"black\" d=\"M5 16 l4 -14 l2 0 l4 14 l-2 0 l-2 -3 l-2 0 l-2 3 z m4 -5.5 l2 0 l-1 -4 z m7 -8.5 l2 0 l0 7 l2 -2 l2 0 l2 2 l0 5 l-2 2 l-2 0 l-2 -2 l0 2 l-2 0 z m2 9 l1 2 l2 0 l1 -1 l0 -2 l-1 -1 l-2 0 z m0 8 l0 2 l-2 -1 l-2 0 l-2 2 l0 2 l2 2 l2 0 l2 -1 l0 2 l-2 1 l-4 0 l-2 -3 l0 -4 l2 -3 l4 0z\" /></svg>"}}</data>
<data>{"addElement":{"elementType":"wikitext","addFunction":"addwikiText","icon":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"30\" height=\"30\" viewbox=\"0 0 30 30\"><text x=\"2\" y=\"18\" style=\"font-size: 12px\">Wiki</text></svg>"}}</data>
//{{{
elementFunctions.getWikiwikitext = function(inputdata,iseditable){
return '<<wikitext [['+inputdata + ']]'+iseditable+'>>\n'
}
elementFunctions.addwikiText = function(elementSet, posindex, copyfrom){
var wikiTextdata = DataTiddler.getData(elementSet.tiddlerName, 'wikiTextdata', {});
var index = 0;
while (typeof(wikiTextdata['wikiTextdata'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"wikitext","data": 'wikiTextdata'+index};
if (typeof(copyfrom) === 'undefined'){
wikiTextdata['wikiTextdata'+index] = '';
} else {
wikiTextdata['wikiTextdata'+index] = wikiTextdata[copyfrom];
}
DataTiddler.setData(elementSet.tiddlerName, 'wikiTextdata', wikiTextdata);
var element = new EbElement(elementdata, true);
elementSet.addElement(element, posindex);
elementSet.save();
}
config.macros.wikitext = {
/**********************************************
* Insert Mathquill-textbox. The content will
* be saved in this tiddler with DataTiddler-plugin
* on each focusout.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var wikiTextid = params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksolwikitext wikitext_'+wikiTextid+'{';
var solclassend = '}}}\n';
var wikiTextdata = DataTiddler.getData(tiddler, 'wikiTextdata', {});
var text = wikiTextdata[wikiTextid] || '';
if (iseditable){
var result = solclassstart + solclassend;
wikify(result, place, null, tiddler);
jQuery(place).find('.wikitext_'+wikiTextid).last().append('<textarea class="wikitextEdit">'+text+'</textarea>');
} else {
var result = solclassstart + '{{solutionwikiText{\n'+text+'\n}}}' + solclassend;
wikify(result, place, null, tiddler);
}
if (iseditable){
var wikiTextelement = jQuery(place).find('.wikitext_'+wikiTextid+' .wikitextEdit');
var edata = {'tiddler': tiddler.title, 'wikiTextid': wikiTextid};
wikiTextelement.focusout(edata, function(e){
var textcontent = jQuery(this).val();
var wikiTextid = e.data.wikiTextid;
var tiddler = e.data.tiddler;
var wikiTextdata = DataTiddler.getData(tiddler, 'wikiTextdata', {});
wikiTextdata[wikiTextid] = textcontent;
DataTiddler.setData(tiddler, 'wikiTextdata', wikiTextdata);
});
}
}
}
//}}}
<<pageselect>>
{{appblock{
<<calculator>>}}}/%
<html>
<iframe width="340" height="575" src="http://web2.0calc.com/widgets/vertical/" scrolling="no" style="border: 1px solid #silver;">
</iframe>
</html>
<<browserapp [[http://web2.0calc.com/widgets/horizontal/]] [[Calculator]]>>
[[web 2.0 scientific calculator|http://web2.0calc.com/]]}}}%/
{{appblock{
!!Geogebra webapp
{{contentlang contentlang_fi{Vaatii Google Drive -tunnuksen ja kirjautumisen alla olevan linkin kautta.}}} {{contentlang contentlang_en{Requires Google Drive -account and login with link below.}}} {{contentlang contentlang_sv{Du behöver Google Drive konto och inloggning. Använd länken nedan.}}} {{contentlang contentlang_et{Sa pead Google Drive-konto ja parool kasutada. Kasutage linki.}}}
<<browserapp [[http://geogebraweb.appspot.com/]] [[Geogebra]]>>
http://geogebraweb.appspot.com/}}}
{{appblock{
!!Desmos.com
<<browserapp [[http://www.desmos.com/calculator]] [[Desmos]]>>
http://www.desmos.com/}}}
{{appblock{
!!Graph.tk
http://graph.tk}}}
<<pageselect>>
{{chatwindow{
!Kurssin keskustelut
[img[chatlog.png]]
<html><input type="text" value="Moikka" style="display:block;" /></html>}}}
<<showCommentList>>
<<showPageComments>><data>{}</data>
<<showCourseCommentList>>
<<showCourseComments>>
{{ebookopening{
<<showNextPage>>
}}}
<<pageinit 0>>
<<showData>>
<data>{"plugins":[]}</data>
!usage
{{{[img[emath-logo-blue.png]]}}}
[img[emath-logo-blue.png]]
!notes
Logo of E-math-project
!type
image/png
!file
./pictures/emath-logo-blue.png
!url
!data
data:image/png;base64,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
/***
|''Name:''|emathdisplaymode.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Tool for showing math in displaymode|
|''Version:''|1.0|
|''Date:''|September 19, 2013|
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130919.1021 ''start''
<<<
!!!!!Code
***/
//{{{
/*
* jquery.emathdisplaymode.js
* jQuery plugin for displaymode math
* and TiddlyWiki macro
*
* E-Math -project http://emath.eu
* Petri Salmela
* License: GNU AGPL
*
*/
(function($){
/**
* emathdisplaymode
* @param options
*/
$.fn.emathdisplaymode = function(options) {
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + options + ' does not exist on jQuery.emathdisplaymode' );
return this;
}
};
var methods = {
init: function( options ){
var settings = $.extend({
latex: '',
editable: false
}, options);
return this.each(function(){
var displaymode = new EmDisplaymode(this, settings);
displaymode.init();
});
},
get: function( options ){
this.trigger('get_data');
return this.data('emathdisplaymode_data'); // return the current value
},
set: function( options ){
if (typeof(options) === 'string'){
this.trigger('set_data', [options]);
}
}
};
var EmDisplaymode = function(place, settings){
this.inited = false;
this.place = $(place);
this.latex = settings.latex;
this.editable = settings.editable;
};
EmDisplaymode.prototype.init = function(){
var mqtype = (this.editable ? 'mathquill-editable' : 'mathquill-embedded-latex');
var html = '<div class="emathdisplaymode"><span class="emdisplaymode-content '+mqtype+'">'+this.latex+'</span></div>';
this.html = $(html);
this.place.html(this.html);
this.html.find('.mathquill-embedded-latex').mathquill();
this.html.find('.mathquill-editable').mathquill('editable');
this.mqcontent = this.html.find('.emdisplaymode-content');
this.initHandlers();
if ($('head style#emathdisplaymodecss').length < 1){
$('head').append('<style type="text/css" id="emathdisplaymodecss">' + this.strings.css + '</style>');
}
};
EmDisplaymode.prototype.initHandlers = function(){
// Init event handlers.
var displaymode = this;
this.mqcontent.bind('focusout.displaymode', function(e){
displaymode.latex = displaymode.mqcontent.mathquill('latex');
displaymode.changed();
});
this.place.bind('get_data', function(e){
$(this).data('emathdisplaymode_data', displaymode.getData());
});
this.place.bind('set_data', function(e, latex){
displaymode.setData(latex);
});
this.place.delegate('.emdisplaymode-content', 'keypress', function(event){
// When enter key is pressed, trigger 'addnext' event to tell the containing box/app about this.
// As extra parameters: the type of this element (emathdisplaymode) and the dom-element
// so that the containing element knows where this happenend an to whom.
if (event.which === 13 && event) {
displaymode.place.trigger('addnext', ['emathdisplaymode', displaymode.place]);
jQuery(this).focusout().blur();
}
});
}
EmDisplaymode.prototype.changeMode = function(iseditmode){
// Change the edit/view mode
this.mqcontent.mathquill('revert');
if (iseditmode) {
this.mqcontent.removeClass('.mathquill-embedded-latex')
.addClass('.mathquill-editable')
.mathquill('editable');
} else {
this.mqcontent.removeClass('.mathquill-editable')
.addClass('.mathquill-embedded-latex')
.mathquill();
}
}
EmDisplaymode.prototype.getData = function(){
// Return the latex content.
this.latex = this.mqcontent.mathquill('latex');
return {latex: this.latex, editable: this.editable};
}
EmDisplaymode.prototype.setData = function(options){
// Set the given data.
if (typeof(options) === 'string') {
this.latex = latex;
} else {
this.latex = options.latex || this.latex;
if (this.editable !== !!options.editable) {
this.editable = !!options.editable || this.editable;
this.changeMode(this.editable)
}
}
this.mqcontent.mathquill('latex', this.latex);
this.changed();
}
EmDisplaymode.prototype.changed = function(){
this.place.trigger('changed');
}
EmDisplaymode.prototype.strings = {
css: [
'.emathdisplaymode {display: block; margin: 0.2em 0; text-align: center;}',
'.emathdisplaymode .emdisplaymode-content {display: inline-block; text-align: left;}'
].join('\n')
};
})(jQuery)
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.emathdisplaymode = {
/******************************
* Show emathdisplaymode
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('Missing displaymode.', place, null, tiddler);
return false;
}
var displaymodeid = params[0];
var iseditable = (params[1] === 'edit'|| params[1] === 'authordialog');
var emtabletext = '{{emathdisplaymodewrapper emathdisplaymode_'+displaymodeid+'{\n}}}';
wikify(emtabletext, place);
if (tiddler) {
var settings = jQuery.extend(true, {}, tiddler.data('emathdisplaymode',{}));
} else {
var settings = {};
}
settings[displaymodeid] = settings[displaymodeid] || {};
settings[displaymodeid].editable = iseditable;
var displaymode = jQuery(place).find('.emathdisplaymodewrapper.emathdisplaymode_'+displaymodeid).last().emathdisplaymode(settings[displaymodeid])
if (iseditable && params[1] !== 'authordialog') {
displaymode.bind('changed', function(e){
var $emdmplace = jQuery(this);
var data = $emdmplace.emathdisplaymode('get');
var settings = tiddler.data('emathdisplaymode', {});
settings[displaymodeid] = data;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tiddler.setData('emathdisplaymode', settings);
config.options.chkAutoSave = autosavestatus;
});
}
return true;
}
}
}
//}}}
/***
|Name|Emathfuncgraph|
|Version|1.1|
|Author|Petri Salmela <pesasa@iki.fi>, Petri Sallasmaa <pekasa@utu.fi>|
|Type|plugin|
|Requires|MathQuill, jQuery, JSXGraph|
|Description|jQuery-plugin for drawing graphs of functions.|
!!!!!Revisions
<<<
20131021.1352 ''Version 1.1''
* Fix the plotting of nth-root. (with negative x)
<<<
<<<
20130910.1107 ''Version 1.0''
* Tweaks on ebook-specific css. (Two page -mode / one page -mode)
<<<
!!!!!Code
***/
//{{{
/*********************************************************
* jquery.emathfuncgraph.js
* jQuery-plugin for drawing functions
* Created by: E-Math -project ( http://emath.eu )
* Petri Salmela
* Petri Sallasmaa
* 26.09.2012
* v.1.1
* Copyright: Four Ferries oy
* http://fourferries.fi
* License: GNU AGPL
********************************************************/
(function($){
// jQuery plugin
$.fn.emathfuncgraph = function(options){
// Test for funcgraph commands and trigger command with options.
if (typeof(options) === 'string'){
var cmd = options;
options = arguments[1] || {};
if (typeof(options) === 'string'){
options = {name: options};
}
// Placeholder variable for returning value.
options.result = this;
this.trigger(cmd, options);
return options.result;
}
// Extend default settings with user given options.
var settings = $.extend({
theme: "default_theme", // html class for other styling
elements: [],
xscale: [-10, 10],
yscale: [-10, 10],
editable: false,
authormode: false,
vertical: false,
listvisible: true,
presentation: false,
decimalperiod: false
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
// Create new Emathfuncgraph object.
var emfuncgraph = new Emathfuncgraph(this, settings);
// Init the emathfuncgraph
emfuncgraph.init();
});
}
var Emathfuncgraph = function(place, settings){
// Constructor for Emathfuncgraph object.
this.settings = settings;
this.place = $(place);
this.place.addClass('emathfuncgraph');
this.theme = this.settings.theme;
this.xscale = this.settings.xscale;
this.yscale = this.settings.yscale;
this.editable = this.settings.editable;
this.authormode = this.settings.authormode;
this.vertical = this.settings.vertical;
this.presentation = this.settings.presentation;
this.listvisible = this.settings.listvisible;
this.decimalperiod = this.settings.decimalperiod;
this.elements = [];
this.elementsByName = {};
// Add new functions and points.
for (var i = 0; i < settings.elements.length; i++){
if (!settings.elements[i].type){
continue;
}
switch (settings.elements[i].type){
case 'function':
this.addFunction(settings.elements[i]);
break;
case 'point':
this.addPoint(settings.elements[i]);
break;
case 'segment':
this.addSegment(settings.elements[i]);
break;
case 'circle':
this.addCircle(settings.elements[i]);
break;
case 'line':
this.addLine(settings.elements[i]);
break;
default:
break;
}
}
// Add css styles if they don't exist already.
if ($('head style#emathfuncgraphstyle').length === 0){
$('head').append('<style id="emathfuncgraphstyle" type="text/css">'+Emathfuncgraph.strings['style']+'</style>');
}
}
Emathfuncgraph.prototype.init = function(){
// Init and draw the functions
var emathfuncgraph = this;
this.place.empty();
if (this.place.hasClass('emathfuncgraph_rendered')){
// return false;
}
this.place.addClass('emathfuncgraph_rendered').addClass(this.settings.theme).attr('vertical', this.vertical);
this.emfgareanumber = -1;
while ($('#emfuncgraph_'+(++this.emfgareanumber)).length > 0){};
var authorbar = '<li'+(!this.listvisible ? ' emfg_listhidden="true"' : '')+'><input type="checkbox" id="emfg_viewcheck_'+this.emfgareanumber+'"'+(!this.listvisible ? 'checked="checked"' : '')+' /><label for="emfg_viewcheck_'+this.emfgareanumber+'" class="emfg_gradbg emfuncgraphtoolbutton emfuncgraphviewmode"><span></span></label></li><li '+(this.editable ? ' emfg_iseditable="true"' : '')+'><input type="checkbox" id="emfg_editcheck_'+this.emfgareanumber+'"'+(this.editable ? ' checked="checked"' : '')+' /><label for="emfg_editcheck_'+this.emfgareanumber+'" class="emfg_gradbg emfuncgraphtoolbutton emfuncgrapheditmode"><span></span></label></li><li><a href="javascript:;" class="emfg_gradbg emfuncgraphtoolbutton emfuncgraphsettings"><span></span></a></li>';
var toolbar = this.isEditable() ? '<ul class="emfuncgraphtoolbar">'+(this.authormode ? authorbar : '')+'<li><a href="javascript:;" class="emfg_gradbg emfuncgraphtoolbutton emfg_presentationmode_button"><span></span></a></li></ul>' : '<ul class="emfuncgraphtoolbar"><li><a href="javascript:;" class="emfg_gradbg emfuncgraphtoolbutton emfg_presentationmode_button"><span></span></a></li></ul>';
this.dispareaid = 'emfuncgraph_'+this.emfgareanumber;
var $emfuncgraph = $('<div class="emfuncgraphwrapper emfg_gradbg"><div id="'+this.dispareaid+'" class="emfuncgraphdisplayarea"></div><div class="emfuncgraphaddarea"></div>'+toolbar+'</div>');
this.place.empty().append($emfuncgraph);
this.displayarea = $emfuncgraph.find('.emfuncgraphdisplayarea');
this.addarea = $emfuncgraph.find('.emfuncgraphaddarea');
this.funcgraph = $emfuncgraph;
if (this.presentation){
this.funcgraph.addClass('emfg_presentation');
}
this.place.find('a.emfg_presentationmode_button').click(function(e){
// Toggle presentation mode.
if ($(this).is('.emfg_presentation a')){
$(this).trigger('stoppresentation');
} else {
$(this).trigger('startpresentation');
}
});
this.place.find('input#emfg_viewcheck_'+this.emfgareanumber).change(function(){
// Toggle viewing of elementlist in show mode.
var hidden = $(this).is(':checked');
emathfuncgraph.listvisible = !hidden;
$(this).parents('li').eq(0).attr('emfg_listhidden', hidden);
emathfuncgraph.changed();
});
this.place.find('input#emfg_editcheck_'+this.emfgareanumber).change(function(){
// Toggle editability of funcgraph.
var editable = $(this).is(':checked');
emathfuncgraph.editable = editable;
$(this).parents('li').eq(0).attr('emfg_iseditable', editable);
emathfuncgraph.changed();
});
this.draw();
return this;
}
Emathfuncgraph.prototype.draw = function(){
// Draw functions and points and show their definitions. Either in edit or show mode.
if (this.isEditable()){
this.edit();
} else {
this.show();
}
this.initEvents();
}
Emathfuncgraph.prototype.edit = function(){
// Show everything in edit mode.
var emfuncgraph = this;
this.place.addClass('emfuncgraph_editmode');
if (this.authormode) {
this.place.addClass('emfuncgraph_authormode');
} else {
this.place.removeClass('emfuncgraph_authormode');
}
this.place.removeClass('emfg_listhidden');
var addarea = '<ul class="emfg_elemlist">';
addarea += '</ul><ul class="emfg_addpanel"><li class="emfg_additem"><a href="javascript:;" class="emfg_gradbg" addtype="point"><span></span></a></li><li class="emfg_additem"><a href="javascript:;" class="emfg_gradbg" addtype="function"><span></span></a></li><li class="emfg_additem"><a href="javascript:;" class="emfg_gradbg" addtype="segment"><span></span></a></li><li class="emfg_additem"><a href="javascript:;" class="emfg_gradbg" addtype="circle"><span></span></a></li><li class="emfg_additem"><a href="javascript:;" class="emfg_gradbg" addtype="line"><span></span></a></li></ul><ul class="emfg_removepanel"></ul></div>';
this.addarea.html(addarea);
this.elemlist = this.addarea.find('ul.emfg_elemlist');
for (var i = 0; i < this.elements.length; i++){
var $elemitem = $('<li></li>');
this.elemlist.append($elemitem);
if (this.elements[i].isReadonly() && !this.authormode){
this.elements[i].drawShowItem($elemitem);
} else {
this.elements[i].drawEditItem($elemitem);
}
}
this.drawElements();
}
Emathfuncgraph.prototype.show = function(){
// Show everithing in show mode.
var emfuncgraph = this;
this.place.removeClass('emfuncgraph_editmode emfuncgraph_authormode');
if (this.listvisible) {
this.place.removeClass('emfg_listhidden');
} else {
this.place.addClass('emfg_listhidden');
}
var addarea = '<ul class="emfg_elemlist" emfg_editable="'+this.isEditable()+'">';
addarea += '</ul>'
this.addarea.html(addarea);
this.elemlist = this.addarea.find('ul.emfg_elemlist');
for (var i = 0; i < this.elements.length; i++){
var $elemitem = $('<li></li>');
this.elemlist.append($elemitem);
this.elements[i].drawShowItem($elemitem);
}
this.drawElements();
}
Emathfuncgraph.prototype.initEvents = function(){
// Init all events.
var emfuncgraph = this;
this.place.unbind('get').bind('get', function(e, options){
// custom event for getting data with jQuery plugin.
return emfuncgraph.getData(options);
});
this.place.unbind('answer').bind('answer', function(e, options){
// custom event for getting data with jQuery plugin.
return emfuncgraph.getAnswer(options);
});
this.place.unbind('add').bind('add', function(e, options){
// custom event for adding elements with jQuery plugin
if (!options || !options.type){
return false;
}
switch (options.type){
case 'function':
emfuncgraph.addFunction(options);
break;
case 'point':
emfuncgraph.addPoint(options);
break;
case 'segment':
emfuncgraph.addSegment(options);
break;
case 'circle':
emfuncgraph.addCircle(options);
break;
case 'line':
emfuncgraph.addLine(options);
break;
default:
break;
}
emfuncgraph.draw();
emfuncgraph.addarea.find('li.emfg_element').last().find('.mathquill-editable').eq(0).focus().focusin();
return true;
});
this.place.unbind('startpresentation').bind('startpresentation', function(e, options){
// custom event for starting presentation with jQuery plugin.
emfuncgraph.placebackup = emfuncgraph.place;
$('body').append('<div id="emfg_presentationwrapper" class="emathfuncgraph emathfuncgraph_rendered '+emfuncgraph.theme+'"></div>');
emfuncgraph.place = $('#emfg_presentationwrapper');
emfuncgraph.place.append(emfuncgraph.funcgraph);
emfuncgraph.funcgraph.addClass('emfg_presentation');
emfuncgraph.presentation = true;
emfuncgraph.draw();
});
this.place.unbind('stoppresentation').bind('stoppresentation', function(e, options){
// custom event for ending presentation with jQuery plugin.
emfuncgraph.funcgraph.removeClass('emfg_presentation');
emfuncgraph.placebackup.append(emfuncgraph.funcgraph);
emfuncgraph.place.remove();
emfuncgraph.place = emfuncgraph.placebackup;
emfuncgraph.presentation = false;
emfuncgraph.draw();
});
this.place.find('ul.emfg_addpanel li.emfg_additem a[addtype]').unbind('click').click(function(e){
// Click on add button to add item (point or function)
$(this).trigger('add', {type: $(this).attr('addtype')});
});
this.displayarea.mouseup(function(){
emfuncgraph.dragUpdate();
emfuncgraph.updateArea();
});
}
Emathfuncgraph.prototype.addFunction = function(options){
// Add new function element
var elemnum = 1;
if (typeof(options.name) === 'undefined' || options.name === ''){
while (typeof(this.elementsByName['f_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'']) !== 'undefined'){
elemnum++;
}
options.name = 'f_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'';
}
if (typeof(options.latex) === 'undefined'){
options.latex = '';
}
options.parent = this;
var newelem = new Emfgfunction(options);
this.elements.push(newelem);
this.elementsByName[newelem.name] = newelem;
this.changed();
}
Emathfuncgraph.prototype.addPoint = function(options){
// Add new point element
var elemnum = 1;
if (typeof(options.name) === 'undefined' || options.name === ''){
while (typeof(this.elementsByName['P_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'']) !== 'undefined'){
elemnum++;
}
options.name = 'P_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'';
}
if (typeof(options.xcoord) === 'undefined'){
options.xcoord = 0;
}
if (typeof(options.ycoord) === 'undefined'){
options.ycoord = 0;
}
options.parent = this;
var newelem = new Emfgpoint(options);
this.elements.push(newelem);
this.elementsByName[newelem.name] = newelem;
this.changed();
}
Emathfuncgraph.prototype.addSegment = function(options){
// Add new segment between two points
var elemnum = 1;
if (typeof(options.name) === 'undefined' || options.name === ''){
while (typeof(this.elementsByName['s_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'']) !== 'undefined'){
elemnum++;
}
options.name = 's_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'';
}
options.parent = this;
var newelem = new Emfgsegment(options);
this.elements.push(newelem);
this.elementsByName[newelem.name] = newelem;
this.changed();
}
Emathfuncgraph.prototype.addCircle = function(options){
// Add new circle element
var elemnum = 1;
if (typeof(options.name) === 'undefined' || options.name === ''){
while (typeof(this.elementsByName['c_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'']) !== 'undefined'){
elemnum++;
}
options.name = 'c_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'';
}
if (typeof(options.x0) === 'undefined'){
options.x0 = 0;
}
if (typeof(options.y0) === 'undefined'){
options.y0 = 0;
}
if (typeof(options.r) === 'undefined'){
options.r = 2;
}
options.parent = this;
var newelem = new Emfgcircle(options);
this.elements.push(newelem);
this.elementsByName[newelem.name] = newelem;
this.changed();
}
Emathfuncgraph.prototype.addLine = function(options){
// Add new line element
var elemnum = 1;
if (typeof(options.name) === 'undefined' || options.name === ''){
while (typeof(this.elementsByName['l_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'']) !== 'undefined'){
elemnum++;
}
options.name = 'l_'+(elemnum < 10 ? elemnum : '{'+elemnum+'}')+'';
}
if (typeof(options.a) === 'undefined'){
options.a = 1;
}
if (typeof(options.b) === 'undefined'){
options.b = 1;
}
if (typeof(options.c) === 'undefined'){
options.c = 1;
}
if (typeof(options.inputtype) === 'undefined') {
options.inputtype = 'normal';
}
options.parent = this;
var newelem = new Emfgline(options);
this.elements.push(newelem);
this.elementsByName[newelem.name] = newelem;
this.changed();
}
Emathfuncgraph.prototype.removeElement = function(index){
// Remove index:th element
delete this.elementsByName[this.elements[index].name];
this.elements.splice(index, 1);
this.addarea.find('li.emfg_element').eq(index).remove();
this.drawElements();
this.changed();
}
Emathfuncgraph.prototype.isEditable = function(){
// Check if the funcgraph is editable. Authormode is always editable.
return this.editable || this.authormode;
}
Emathfuncgraph.prototype.getData = function(options){
// Get all data as an object.
result = {
theme: this.theme,
xscale: this.xscale,
yscale: this.yscale,
editable: this.editable,
listvisible: this.listvisible,
elements: []
}
for (var i = 0; i < this.elements.length; i++){
result.elements.push(this.elements[i].getData());
}
options.result = result;
return result;
}
Emathfuncgraph.prototype.getAnswer = function(options){
// Get data of all non-readonly objects.
result = {
elements: []
};
for (var i = 0; i < this.elements.length; i++) {
if (!this.elements[i].isReadonly()) {
result.elements.push(this.elements[i].getData());
}
}
options.result = result;
return result;
}
Emathfuncgraph.prototype.drawElements = function(){
// (Re)draw all graphs of elements.
if (this.board){
JXG.JSXGraph.freeBoard(this.board);
}
this.displayarea.empty();
this.construction = [];
this.board = JXG.JSXGraph.initBoard(this.dispareaid, {grid: true, boundingbox: [this.xscale[0], this.yscale[1], this.xscale[1], this.yscale[0]], keepaspectratio: true, axis: false, showNavigation: this.isEditable(), showCopyright: false});
this.board.create('axis', [[0,0],[1,0]],{ticks:{insertTicks: false, ticksDistance: 5, minTicksDistance: 10, majorHeight: 5, minorHeight: 0, strokeWidth: 2, strokeOpacity: 0.5}});
this.board.create('axis', [[0,0],[0,1]],{ticks:{insertTicks: false, ticksDistance: 5, minTicksDistance: 10, majorHeight: 5, minorHeight: 0, strokeWidth: 2, strokeOpacity: 0.5}});
this.board.suspendUpdate();
// Draw invisible origo, unitpoints and vertical and horizontal lines.
this.construction.push(this.board.construct('Origopoint(0,0) invisible; Xunitpoint(1,0) invisible; Yunitpoint(0,1) invisible; horizontalline=]Origopoint Xunitpoint[ invisible; verticalline=]Origopoint Yunitpoint[ invisible;'));
this.elemstoshow = this.elements.slice(0);
this.elemstoshow.reverse();
var lastlength = this.elemstoshow.length + 1;
while (lastlength > this.elemstoshow.length){
// Draw all drawable elements, if dependencies are not met, postpone drawing and try again.
// Keep drawing as long as something gets drawn.
lastlength = this.elemstoshow.length;
for (var i = lastlength-1; i > -1; i--){
var success = true;
if (this.hasElemsDrawn(this.elemstoshow[i].getDeps())){
success = this.elemstoshow[i].draw();
} else {
success = false;
}
if (success){
this.elemstoshow.splice(i,1);
}
}
}
this.board.unsuspendUpdate();
JXG.removeEvent(this.board.containerObj, "mousewheel", this.board.mouseWheelListener, this.board);
JXG.removeEvent(this.board.containerObj, "DOMMouseScroll", this.board.mouseWheelListener, this.board);
}
Emathfuncgraph.prototype.changeColor = function($lielem, elemnum){
// Show the color selector for given element.
var emfuncgraph = this;
var currentcolor = $lielem.find('a.emfg_elemtools_color').attr('color');
var menuhtml = '<div class="colorselectwrapper"><ul class="colorselector emfg_gradbg">';
for (var i = 0; i < Emathfuncgraph.colors.length; i++){
var colorstr = Emathfuncgraph.colors[i];
menuhtml += '<li class="'+(colorstr === currentcolor ? 'emfg_currentcolor' : '')+'"><a href="javascript:;" color="'+colorstr+'"><span></span></a></li>';
}
menuhtml += '</ul></div>';
$lielem.append(menuhtml).find('.colorselector').hide().fadeIn(300).find('li a[color]').click(function(){
// Init click handlers for buttons in color selector.
var color = $(this).attr('color');
emfuncgraph.setColor(elemnum, color);
$lielem.find('a.emfg_elemtools_color[color]').attr('color', color).removeClass('isopen').focus();
$(this).parents('div.colorselectwrapper').fadeOut(300, function(){$(this).remove()});
emfuncgraph.changed();
}).eq(0).focus();
return true;
}
Emathfuncgraph.prototype.setColor = function(index, color){
if (typeof(color) === 'undefined'){
color = this.elements[index].getColor();
}
this.elements[index].setColor(color);
}
Emathfuncgraph.prototype.hasElemsDrawn = function(elemlist){
var result = true;
for (var i = 0; i < elemlist.length; i++){
result = result && elemlist[i] !== '' && (typeof(this.board.elementsByName[elemlist[i]]) === 'object');
}
return result;
}
Emathfuncgraph.prototype.dragUpdate = function(){
// Check all points, if they have been moved and update object and mathquill text, if needed.
//var coords = {xcoord: 0, ycoord: 0};
//var jsxcoords;
var currelem;
//var $listitem;
var changed = false;
for (var i = 0; i < this.elements.length; i++){
currelem = this.elements[i];
changed = currelem.dragUpdate() || changed;
}
if (changed){
this.changed();
this.draw();
}
}
Emathfuncgraph.prototype.updateArea = function(){
var bbox = this.board.getBoundingBox();
if (this.xscale[0] != bbox[0] || this.xscale[1] != bbox[2] || this.yscale[0] != bbox[1] || this.yscale[1] != bbox[3]){
var size = Math.min(bbox[2]-bbox[0], bbox[1]-bbox[3]);
this.xscale[0] = bbox[0]; // left side
this.yscale[1] = bbox[1]; // top side
// To make the bounding box square, use same size for width and height.
this.xscale[1] = this.xscale[0] + size; // right side
this.yscale[0] = this.yscale[1] - size; // bottom side
}
}
Emathfuncgraph.prototype.changed = function(){
// Trigger a "emathfuncgraph_changed"-event so that containing page/application/whatever knows to save
// or do whatever it needs to do.
var e = jQuery.Event("emathfuncgraph_changed");
this.place.trigger( e );
}
Emathfuncgraph.latex2js = function(expression, needjs){
// Simple conversion of LaTeX formulas to Javascript math-expression with at most one variable (x).
// Functions that can be nested, should be replaced repeatedly from innermost to the outermost.
var latexrep = [
[/\\sqrt{([^{}]*)}/ig, 'sqrt($1)'],
[/\\sqrt\[([0-9]+)\]{([^{}]*)}/ig, '((($2)/(abs($2)))^($1))*((((($2)/(abs($2)))^($1+1))*abs($2))^(1/$1))'],
[/\\lg\\left\(([^\(\)]+)\\right\)/g, '((log($1))/(log(10)))'],
[/\\log_(?:{([0-9]+)}|([0-9]))\\left\(([^\(\)]+)\\right\)/g, '((log($3))/(log($1$2)))'],
[/\\left\|([^\|]*)\\right\|/g, 'abs($1)'],
[/\\frac{([^{}]*)}{([^{}]*)}/ig, '(($1)/($2))']
];
// Some LaTeX-markings need to be replaced only once.
var reponce = [
[/\\left\(/ig, '('],
[/\\right\)/ig, ')'],
[/\)\(/ig, ')*('],
[/([0-9])\(/ig, '$1*('],
[/\^([0-9])/ig, '^($1)'],
[/\\sin/ig, 'sin'],
[/\\cos/ig, 'cos'],
[/\\tan/ig, 'tan'],
[/\\ln/ig, 'log'],
[/\\pi/ig, 'Pi'],
[/([0-9])([a-z])/ig, '$1*$2'],
[/{/ig, '('],
[/}/ig, ')'],
[/,/ig, '.'],
[/\\cdot/ig, '*'],
[/e/g, 'Exp(1)'],
[/([0-9]+)Exp/g, '$1*Exp'],
[/\)x/g, ')*x'],
[/\)Pi/g, ')*Pi'],
[/Pi Exp/g, 'Pi*Exp']
];
var oldexpr = '';
while (oldexpr !== expression){
// Replace strings as long as the expression keeps changing.
oldexpr = expression;
for (var i = 0; i < latexrep.length; i++){
expression = expression.replace(latexrep[i][0], latexrep[i][1]);
}
}
for (var i = 0; i < reponce.length; i++){
// Do one-time replacements.
expression = expression.replace(reponce[i][0], reponce[i][1]);
}
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>\\?:])/ig,
valid = true;
expression = expression.replace(reg, function(word){
// Check that all math functions / variables that can be found from Javascript's Math-object.
if(word !=="x" && word !== "Pi" && word !== "Exp" && !Math.hasOwnProperty(word)){
valid = false;
}
return word;
});
if (expression.indexOf('\\') != -1){
// If there are still backslashes, there are still some LaTeX commands that have not been replaced.
valid = false;
}
return !valid ? "INVALID" : expression;
}
Emathfuncgraph.latexeval = function(expression){
// Simple evaluator for math expressions. Converts LaTeX expression (without variables) to Javascript expression
// and tries to evaluate it to a number.
expression = '' + expression;
// Functions that can be nested, should be replaced repeatedly from innermost to the outermost.
var latexrep = [
[/\\sqrt{([^{}]*)}/ig, 'sqrt($1)'],
[/\\lg\\left\(([^\(\)]+)\\right\)/g, '((log($1))/(log(10)))'],
[/\\frac{([^{}]*)}{([^{}]*)}/ig, '(($1)/($2))'],
[/\\left\|([^\|]*)\\right\|/g, 'abs($1)'],
[/((?:[0-9]+)|(?:\([^\(\)]\)))\^((?:[0-9])|(?:{[0-9]+}))/ig, 'pow($1, $2)']
]
// Some LaTeX-markings need to be replaced only once.
var reponce = [
[/\\sin/ig, 'sin'], // Replace sin
[/\\cos/ig, 'cos'], // Replace cos
[/\\tan/ig, 'tan'], // Replace tan
[/\\ln/ig, 'log'], // Replace ln
[/\\pi/ig, 'PI'], // Replace PI
[/\\left\(/ig, '('], // Replace left parenthesis )
[/\\right\)/ig, ')'], // Replace right parenthesis
[/(sin|cos|tan)\(([^\^\)]+)\^{\\circ}/ig, '$1($2*PI/180'], // Replace degrees with radians inside sin, cos and tan
[/{/ig, '('], // Replace left bracket
[/}/ig, ')'], // Replace right bracket
[/,/ig, '.'], // Replace periods with points
[/\)\(/ig, ')*('], // Add times between ending and starting parenthesis )
[/\\cdot/ig, '*'], // Replace cdot with times
[/([0-9]+)PI/ig, '$1*PI'],
[/e/g, 'E'],
[/([0-9]+)E/g, '$1*E'],
[/EPI/g, 'E*PI'],
[/PI E/g, 'PI*E']
]
var oldexpr = '';
while (oldexpr !== expression){
// Replace strings as long as the expression keeps changing.
oldexpr = expression;
for (var i = 0; i < latexrep.length; i++){
expression = expression.replace(latexrep[i][0], latexrep[i][1]);
}
}
for (var i = 0; i < reponce.length; i++){
expression = expression.replace(reponce[i][0], reponce[i][1]);
}
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig,
valid = true;
expression = expression.replace(reg, function(word){
if (Math.hasOwnProperty(word)){
return 'Math.'+word;
} else {
valid = false;
return word;
}
});
if (!valid){
throw 'Invalidexpression';
} else {
try {
return (new Function('return ('+expression+')'))();
} catch (err) {
throw 'Invalidexpression';
}
}
}
// Available colors for points and function graphs.
Emathfuncgraph.colors = [
'red',
'blue',
'green',
'orange',
'darkviolet',
'yellow',
'brown',
'black',
'gray',
'fuchsia',
'lime',
'navy',
'#B5863B'
];
// Some constant strings: css-styles,...
Emathfuncgraph.strings = {
style: '.emathfuncgraph {text-align: center;}'
+'.emfuncgraphwrapper {display: inline-block; border: 1px solid black; position: relative; border-radius: 4px; text-align: left; white-space: nowrap; padding-bottom: 30px;}'
+'.emathfuncgraph.emfg_listhidden .emfuncgraphaddarea {display: none;}'
+'.emathfuncgraph label {cursor: pointer;}'
+'.emfuncgraphdisplayarea {width: 400px; height: 400px; border: 1px solid #777; margin: 8px; background-color: white; box-shadow: inset 2px 2px 6px rgba(0,0,0,0.2), -1px -1px 1px #ccc, 1px 1px 1px #fff; border-radius: 4px; display: inline-block;}'
+'.emfuncgraphaddarea {position: relative; display: inline-block; width: 380px; vertical-align: top; white-space: normal;}'
+'.emfuncgraphaddarea ul {list-style: none; padding: 0; margin: 8px;}'
+'.emfuncgraphaddarea ul.emfg_elemlist {max-height: 360px; height: 330px; background-color: #aaa; overflow-y: auto; overflow-x: hidden; border: 1px solid #999; border-radius: 4px; box-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;}'
+'.emfuncgraphaddarea li.emfg_element {margin: 0; padding: 0.1em 0 0.1em 0; border-bottom: 1px solid #999; border-top: 1px solid white; position: relative; min-height: 20px; overflow: visible;}'
+'.emfuncgraphaddarea li.emfg_element .mathquill-editable {background-color: white; padding: 0.1em 0.3em; border: 1px solid #aaa;}'
+'.emfuncgraphaddarea li.emfg_element .mathquill-editable.emfg_error {background-color: #fcc;}'
+'.emfuncgraphdisplayarea svg {height: 100%; width: 100%;}'
+'.emathfuncgraph[vertical="true"] .emfuncgraphwrapper {white-space: normal;}'
+'.emathfuncgraph[vertical="true"] .emfuncgraphwrapper .emfuncgraphdisplayarea {display: block; width: 400px; height: 400px;}'
+'.emathfuncgraph[vertical="true"] .emfuncgraphwrapper .emfuncgraphaddarea {display: block; width: auto;}'
+'.emathfuncgraph[vertical="true"].emfg_listhidden .emfuncgraphwrapper .emfuncgraphaddarea {display: none;}'
+'.emathfuncgraph[vertical="true"] .emfuncgraphwrapper .emfuncgraphaddarea ul.emfg_elemlist {height: auto;}'
// Emathbook specific
+'#contentWrapper[pageopen] .emathfuncgraph[vertical="false"] .emfuncgraphwrapper {white-space: normal;}'
+'#contentWrapper[pageopen] .emathfuncgraph[vertical="false"] .emfuncgraphwrapper .emfuncgraphdisplayarea {display: block; width: 400px; height: 400px;}'
+'#contentWrapper[pageopen] .emathfuncgraph[vertical="false"]:not(.emfg_listhidden) .emfuncgraphwrapper .emfuncgraphaddarea {display: block; width: auto;}'
+'#contentWrapper[pageopen] .emathfuncgraph[vertical="false"] .emfuncgraphwrapper .emfuncgraphaddarea ul.emfg_elemlist {height: auto;}'
+'ul.emfg_addpanel li.emfg_additem, ul.emfg_removepanel li.emfg_removeitem {display: inline-block;}'
+'ul.emfg_addpanel li.emfg_additem a, ul.emfg_removepanel li.emfg_removeitem a {display: block; width: 30px; height: 20px; border: 1px solid #777; border-radius: 5px; margin-right: 8px; display: inline-block; box-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;}'
+'ul.emfg_addpanel {float: left; display: inline-block;}'
+'ul.emfg_removepanel {float: right; display: inline-block;}'
+'.emfg_gradbg {background: rgb(255,255,255); /* Old browsers */'
+'background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%); /* FF3.6+ */'
+'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1))); /* Chrome,Safari4+ */'
+'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Chrome10+,Safari5.1+ */'
+'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* Opera 11.10+ */'
+'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* IE10+ */'
+'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%); /* W3C */'
+'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffff\', endColorstr=\'#e5e5e5\',GradientType=0 ); /* IE6-9 */}'
+'.emathfuncgraph.emfuncgraph_editmode .emfuncgraphwrapper {padding-bottom: 0px;}'
+'.emathfuncgraph .emfuncgraphtoolbar {position: absolute; right: 5px; bottom: 5px; margin: 0; padding: 0;}'
+'.emathfuncgraph .emfuncgraphtoolbar li {display: inline-block; margin: 0 2px 0 0; padding: 0;}'
+'.emathfuncgraph .emfuncgraphtoolbar input[type="checkbox"] {display: none;}'
+'.emathfuncgraph a[addtype] span, .emathfuncgraph a.emfg_presentationmode_button span, .emathfuncgraph .emfuncgraphtoolbutton span, .emathfuncgraph .emfg_elemtools_lockelem span {display: block; width: 30px; height: 20px; margin: 0 auto; border-radius: 4px; background: transparent url(data:image/png;base64,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) 0 0 no-repeat;}'
+'.emathfuncgraph a[addtype="point"] span {background-position: center 0;}'
+'.emathfuncgraph a[addtype="function"] span {background-position: center -20px;}'
+'.emathfuncgraph a[addtype="segment"] span {background-position: center -40px;}'
+'.emathfuncgraph a[addtype="circle"] span {background-position: center -60px;}'
+'.emathfuncgraph a[addtype="line"] span {background-position: center -80px;}'
+'.emathfuncgraph a[addtype]:hover span, .emathfuncgraph .emfuncgraphtoolbar a:hover span, .emathfuncgraph .emfuncgraphtoolbar label:hover span, .emathfuncgraph .emfg_elemtools_lockelem:hover span, .emathfuncgraph .emfg_elemtools_removeelem:hover span, .emathfuncgraph .emfg_elemtools_color:hover span {background-color: rgba(255,255,255,0.5);}'
+'.emathfuncgraph .emfg_elemtools_lockelem span {width: 20px; height: 20px; background-position: left 20px;}'
+'.emathfuncgraph li[emfgelemtype="point"] .emfg_elemtools_lockelem span, .emathfuncgraph li[emfgelemtype="circle"] .emfg_elemtools_lockelem span, .emathfuncgraph li[emfgelemtype="segment"] .emfg_elemtools_lockelem span {width: 20px; height: 20px; background-position: left -180px;}'
+'.emathfuncgraph li[emfg_locked="true"] .emfg_elemtools_lockelem span {width: 20px; height: 20px; background-position: left 20px;}'
+'.emathfuncgraph.emfuncgraph_authormode li[emfg_locked="false"] .emfg_elemtools_lockelem span {width: 20px; height: 20px; background-position: left -160px;}'
+'.emathfuncgraph.emfuncgraph_authormode li[emfg_locked="true"] .emfg_elemtools_lockelem span {width: 20px; height: 20px; background-position: left -140px;}'
+'.emathfuncgraph .emfuncgraphtoolbar .emfuncgraphtoolbutton {display: inline-block; border: 1px solid #777; border-radius: 4px; margin: 3px 5px 3px 5px; box-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;}'
+'.emathfuncgraph a.emfg_presentationmode_button span {background-position: center -100px;}'
+'.emathfuncgraph .emfg_presentation a.emfg_presentationmode_button span {background-position: center -120px;}'
+'.emathfuncgraph a.emfuncgraphsettings span {background-position: center -200px;}'
+'.emathfuncgraph label.emfuncgraphviewmode span {background-position: center -220px;}'
+'.emathfuncgraph li[emfg_listhidden="true"] label.emfuncgraphviewmode span {background-position: center -240px;}'
+'.emathfuncgraph label.emfuncgrapheditmode span {background-position: center -320px;}'
+'.emathfuncgraph li[emfg_iseditable="true"] label.emfuncgrapheditmode span {background-position: center -300px;}'
+'.emathfuncgraph .emfg_element_content {display: inline-block; margin-left: 0.2em; margin-right: 55px;}'
+'.emathfuncgraph .emfg_elemtools {display: inline-block; margin: 2px 0.5em 2px 2px; padding: 0;}'
+'.emathfuncgraph .emfg_elemtools_right {position: absolute; right: 2px; top: 2px; display: inline-block; margin: 2px; padding: 0;}'
+'.emathfuncgraph .emfg_elemtools_right input.emfg_lockcheck {display: none;}'
+'.emathfuncgraph .emfg_options_showhide {display: block; text-align: center; text-decoration: none; color: black; font-size: 100%; text-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5); line-height: 0.3em; height: 0.6em; overflow: hidden;}'
+'.emathfuncgraph .emfg_options_showhide:hover {background-color: rgba(255,255,255,0.7);}'
+'.emathfuncgraph .emfgitem_options {background-color: white; border-radius: 0px; box-shadow: inset 0px 2px 3px rgba(0,0,0,0.3); margin: 0 0.1em 0.4em 0.1em; padding: 0.3em; border: 1px solid #aaa;}'
//+'.emathfuncgraph li.emfg_element[emfg_readonly="true"] .emfg_elemtools_right {visibility: hidden;}'
+'.emathfuncgraph li.emfg_element[emfg_readonly="true"] .emfg_elemtools_color, .emathfuncgraph ul[emfg_editable="false"] li.emfg_element .emfg_elemtools_color {background: transparent; border: 1px solid transparent; cursor: default; box-shadow: none;}'
+'.emathfuncgraph .emfg_range {display: inline-block; margin-left: 1.5em; padding: 0 0.2em; position: absolute; right: 1em; bottom: 0.2em; font-size: 70%;}'
+'.emathfuncgraph .emfg_elemtools_color, .emathfuncgraph .colorselector li a[color], .emathfuncgraph .emfg_elemtools_removeelem, .emathfuncgraph.emfuncgraph_authormode .emfg_elemtools_lockelem {display: inline-block; width: 20px; height: 20px; border: 1px solid #999; border-radius: 4px; position: relative; box-shadow: 0 0 1px rgba(0,0,0,0.5); box-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff; cursor: pointer;}'
+'.emathfuncgraph .emfg_elemtools_lockelem {display: inline-block; width: 20px; height: 20px; border-radius: 4px; position: relative; cursor: default;}'
+'.emathfuncgraph .colorselector li a[color] {display: block;}'
+'.emathfuncgraph .colorselector li.emfg_currentcolor a[color] {background-color: rgba(0,0,0,0.3); border-top: 1px solid #555; border-left: 1px solid #555;}'
+'.emathfuncgraph .emfg_elemtools_color.isopen {border-color: red; background: #aaa;}'
+'.emathfuncgraph .emfg_elemtools_color span, .emathfuncgraph .colorselector a[color] span {display: inline-block; width: 16px; height: 16px; border-radius: 8px; position: absolute; top: 2px; left: 2px;}'
+'.emathfuncgraph .emfg_elemtools_color[color="red"] span, .emathfuncgraph .colorselector a[color="red"] span {background-color: red;}'
+'.emathfuncgraph .emfg_elemtools_color[color="blue"] span, .emathfuncgraph .colorselector a[color="blue"] span {background-color: blue;}'
+'.emathfuncgraph .emfg_elemtools_color[color="green"] span, .emathfuncgraph .colorselector a[color="green"] span {background-color: green;}'
+'.emathfuncgraph .emfg_elemtools_color[color="orange"] span, .emathfuncgraph .colorselector a[color="orange"] span {background-color: orange;}'
+'.emathfuncgraph .emfg_elemtools_color[color="darkviolet"] span, .emathfuncgraph .colorselector a[color="darkviolet"] span {background-color: darkviolet;}'
+'.emathfuncgraph .emfg_elemtools_color[color="yellow"] span, .emathfuncgraph .colorselector a[color="yellow"] span {background-color: yellow;}'
+'.emathfuncgraph .emfg_elemtools_color[color="brown"] span, .emathfuncgraph .colorselector a[color="brown"] span {background-color: brown;}'
+'.emathfuncgraph .emfg_elemtools_color[color="black"] span, .emathfuncgraph .colorselector a[color="black"] span {background-color: black;}'
+'.emathfuncgraph .emfg_elemtools_color[color="gray"] span, .emathfuncgraph .colorselector a[color="gray"] span {background-color: gray;}'
+'.emathfuncgraph .emfg_elemtools_color[color="lime"] span, .emathfuncgraph .colorselector a[color="lime"] span {background-color: lime;}'
+'.emathfuncgraph .emfg_elemtools_color[color="fuchsia"] span, .emathfuncgraph .colorselector a[color="fuchsia"] span {background-color: fuchsia;}'
+'.emathfuncgraph .emfg_elemtools_color[color="navy"] span, .emathfuncgraph .colorselector a[color="navy"] span {background-color: navy;}'
+'.emathfuncgraph .emfg_elemtools_color[color="#B5863B"] span, .emathfuncgraph .colorselector a[color="#B5863B"] span {background-color: #B5863B;}'
+'.emathfuncgraph ul.colorselector {list-style: none; position: absolute; top: -6px; left: -7px; width: auto; padding: 2px; border: 1px solid #777; border-radius: 4px; z-index: 10; box-shadow: 4px 4px 4px rgba(0,0,0,0.5);}'
+'.emathfuncgraph ul.colorselector li {display: inline-block; padding: 0; margin: 0;}'
+'.emathfuncgraph .emfg_elemtools_removeelem span {display: block; width: 20px; height: 20px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAElQAABJUBWL5jxAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAF1SURBVDiNrdQ9i1NBFMbx37kJi+DCam1KIYr6ASwEOy1EsHYLwS9ibS3Y2dn7RUR8BastXF8KSQLuanSzORZ3gtckN8mip5rzMv85z8xwIjP9T+uuK3gTcb/iAnLK3uXMxycCvorod7k684PdKc+Co+Duu4gfs9wxz69kvl4J7NLHvQZQcKe4k2auwy+sBk55gQerZDWA75c09LcFt/FIffpWCR/V+1XFH+NUsounzf2VOQuGkNwK9krsIZ6U9ceKG83alUAMSmKcfC2xg+CwrL9M6o4dM9oEODv1NA7mk8mow85cbTuw+lO0vQyI0bQAqw2BgwbwcD4fjCrOwNYmwE/lXrJF8pRR1h2Oz2f+XAu8njnBNy2Sg1HUwIXulgKLDbAdLZKzlnwi4NB6yQtfZh2w9ZWDnWWfehVwoOWVq7qzVslt83AYXMN3yHqcnS25m0G/DJEFi2UT+2XEuQ6X0KvoJb2aaz/4EOzj7cXMzxsB/8V+A2xJeyQvlXgTAAAAAElFTkSuQmCC) center center no-repeat;}'
+'.emfuncgraphwrapper.emfg_presentation {position: fixed; top: 1em; right: 1em; bottom: 1em; left: 1em; font-size: 120%; padding: 0.5em; z-index: 1000;}'
+'.emfuncgraphwrapper.emfg_presentation .emfuncgraphaddarea {position: absolute; right: 0.2em; top: 0.2em; bottom: 0.2em; width: 30%; box-sizing: border-box;}'
+'.emfuncgraphwrapper.emfg_presentation .emfuncgraphaddarea ul.emfg_elemlist {max-height: none; height: auto; position: absolute; top: 0; right: 0; left: 0; bottom: 80px; border: 1px solid #777;}'
+'.emfuncgraphwrapper.emfg_presentation .emfuncgraphaddarea .emfg_addpanel {position: absolute; left: 0; bottom: 30px; right: 0;}'
+'.emfuncgraphwrapper.emfg_presentation .emfuncgraphdisplayarea {position: static; margin: 0; margin-right: auto; width: 70%; height: 100%; display: block; box-sizing: border-box;}'
+'.emfg_listhidden .emfuncgraphwrapper.emfg_presentation .emfuncgraphdisplayarea {width: 100%;}'
+'.emathfuncgraph .JXGtext {font-family: times, serif; font-size: 100%!important;}'
}
/************************************************
* Emfgelement -class
* Parent class for elements in graph.
* All elements inherit prototypes from this class.
************************************************/
var Emfgelement = function(options){
// General constructor for elements
}
// Reference to the parent class so that parent's methods can be used.
Emfgelement.prototype.parentClass = Emfgelement.prototype;
Emfgelement.prototype.changed = function(){
// Signal the change
this.parent.changed();
}
Emfgelement.prototype.redrawAll = function(){
// Redraw all elements.
this.parent.drawElements();
}
Emfgelement.prototype.getLabel = function(){
// Get the label of the element in LaTex
return this.name;
}
Emfgelement.prototype.getData = function(){
// Get the data as an object for saving of what ever.
var result = {
type: this.type,
name: this.name,
color: this.color,
readonly: this.readonly
}
return result;
}
Emfgelement.prototype.getDeps = function(){
// Return the list of names of elements this element depends of.
// (Elements that are needed before this can be drawn.)
return [];
}
Emfgelement.prototype.getColor = function(){
// Get the current color of this element.
return this.color;
}
Emfgelement.prototype.isReadonly = function(){
// Check if this function is readonly
return this.readonly;
}
Emfgelement.prototype.isInvalid = function(){
// Check if this element is in invalid state. For default: always false.
return false;
}
Emfgelement.prototype.initExtraOptions = function(){
// Init function for eventhandlers of extra options for this element. Dummy default.
return true;
}
Emfgelement.prototype.dragUpdate = function(){
// Check if the element has been dragged and update data and picture.
// By default do nothing.
return false;
}
Emfgelement.prototype.markErrors = function(){
var $mqelems = this.listitem.find('.mathquill-editable');
if (!this.valid){
for (var i = 0; i < this.invalids.length; i++){
$mqelems.eq(this.invalids[i]).addClass('emfg_error');
}
} else {
$mqelems.removeClass('emfg_error');
}
}
Emfgelement.prototype.draw = function(){
// Draw this element.
var element = this;
var board = this.parent.board;
var construction = this.parent.construction;
var success = false;
if (this.isInvalid()){
return false;
}
var drawops = this.getDrawOptions();
for (var i = 0; i < drawops.length; i++){
if (this.parent.presentation){
drawops[i].options.strokeWidth = 2* drawops[i].options.strokeWidth;
}
try {
var constr = {};
constr[drawops[i].options.name] = board.create(drawops[i].drawtype, drawops[i].parents, drawops[i].options);
construction.push(constr);
success = true;
} catch (err){
// If jsxgraph could not draw.
if (this.listitem){
this.listitem.find('.mathquill-editable').addClass('emfg_error');
}
success = false;
}
}
return success;
}
Emfgelement.prototype.drawEditItem = function($elemitem){
// Draw the list item on the elementlist.
var element = this;
var elemlist = this.parent.elemlist;
if ($elemitem){
this.listitem = $elemitem;
}
if (!this.listitem){
return false;
}
this.listitem.addClass('emfg_element emfg_gradbg')
.attr('emfgelemtype', this.type)
.attr('emfgelemname',this.name)
.attr('emfg_readonly',(this.isReadonly() && !this.parent.authormode))
.attr('emfg_locked', (this.isReadonly() && this.parent.authormode));
var elemsettings = this.getEditItem();
this.listitem.html(elemsettings);
this.listitem.find('.mathquill-editable:not(mathquill-rendered-math)').mathquill('editable');
this.listitem.find('.mathquill-embedded-latex:not(mathquill-rendered-math)').mathquill();
this.listitem.find('.mathquill-editable');
this.listitem.find('.emfg_element_content .mathquill-editable').bind('focusout.emfg', function(e){
var error = false;
var $mqelem = $(this);
var data = element.getInputData();
element.setElement(data);
element.markErrors();
element.changed();
element.redrawAll();
});
this.listitem.find('.mathquill-editable').bind('keyup.emfg', function(e){
// Enter sends focusout and blur events for mathquill boxes.
if (e.which == 13){
$(this).focusout();
}
});
this.listitem.find('.emfgitem_options').hide();
this.listitem.find('a.emfg_options_showhide').click(function(){
if ($(this).hasClass('open')){
$(this).removeClass('open').prev().slideUp('fast');
} else {
$(this).addClass('open').prev().slideDown('fast');
}
});
this.listitem.find('a.emfg_elemtools_removeelem').click(function(e){
// Click on remove button to remove this item.
var $lielem = $(this).parents('li.emfg_element');
var elindex = $lielem.index();
if (confirm('You are about to remove '+element.type+': '+element.name)){
element.parent.removeElement(elindex);
}
});
this.listitem.filter('[emfg_readonly="false"]').find('.emfg_elemtools a.emfg_elemtools_color').click(function(e){
// Click on color chooser.
var $lielem = $(this).addClass('isopen').parents('li.emfg_element');
var elindex = $lielem.index();
element.parent.changeColor($lielem, elindex);
});
this.initExtraOptions();
if (this.parent.authormode) {
this.initAuthorEvents();
}
return true;
}
Emfgelement.prototype.drawShowItem = function($elemitem){
// Draw the list item on the elementlist in show mode.
var elemlist = this.parent.elemlist;
this.listitem = $elemitem;
this.listitem.addClass('emfg_element emfg_gradbg')
.attr('emfgelemtype', this.type)
.attr('emfgelemname',this.name)
.attr('emfg_readonly',this.isReadonly())
.attr('emfg_locked', this.isReadonly() && !this.parent.authormode);
var elemsettings = this.getShowItem();
this.listitem.html(elemsettings);
this.listitem.find('.mathquill-embedded-latex:not(mathquill-rendered-math)').mathquill();
}
Emfgelement.prototype.lockHtml = function(authormode){
// Return the html-code for lock symbol and checkbox.
var lockstring = [
'<span class="emfg_lock_options">',
(authormode ? '<input type="checkbox" id="emfg_'+this.type+'_'+this.simplename+'_locked" class="emfg_lockcheck" '+(this.readonly ? 'checked="checked" ' : '')+'/>' : ''),
'<label class="emfg_elemtools_lockelem'+(this.parent.authormode ? ' emfg_gradbg' : '')+'" for="emfg_'+this.type+'_'+this.simplename+'_locked"><span></span></label>',
'</span>'
].join('');
return lockstring;
}
Emfgelement.prototype.initAuthorEvents = function(){
// Init events that are used in author mode.
var element = this;
this.listitem.find('#emfg_'+this.type+'_'+this.simplename+'_locked').change(function(){
element.readonly = $(this).is(':checked');
element.listitem.attr('emfg_locked', element.readonly);
element.changed();
element.redrawAll();
});
}
/************************************************
* Emfgfunction -class
* Function elements in graph
************************************************/
var Emfgfunction = function(options){
// Representation of a function
this.type = 'function';
this.name = options.name;
this.simplename = this.name.replace(/[{}]/g, '');
this.latex = options.latex;
this.color = options.color || 'blue';
this.min = options.min || '';
this.max = options.max || '';
this.readonly = !!options.readonly;
this.parent = options.parent;
if (this.latex && !this.js){
this.js = Emathfuncgraph.latex2js(this.latex);
}
}
// Inherit prototypes from Emfgelement, override constructor with own one.
Emfgfunction.prototype = new Emfgelement();
Emfgfunction.prototype.constructor = Emfgfunction;
Emfgfunction.prototype.getLabel = function(){
// Get the label of the value of function as name(x) in LaTeX
return this.name + '\\left(x\\right)';
}
Emfgfunction.prototype.getData = function(){
// Get all data of the function as an object.
// Use the default fields defined in parent class and add some own fields.
var result = this.parentClass.getData.call(this);
result.latex = this.latex;
result.max = this.max;
result.min = this.min;
return result;
}
Emfgfunction.prototype.setFunction = function(latex){
// Set the function from LaTeX string. Normalize the decimal separator to '.'.
this.valid = true;
this.invalids = [];
this.latex = latex.replace(/,/g, '.');
if (this.latex){
this.js = Emathfuncgraph.latex2js(this.latex);
} else {
this.js = 'INVALID';
}
if (this.isInvalid()){
this.valid = false;
this.invalids = [0];
}
}
// Common alias for set-method.
Emfgfunction.prototype.setElement = Emfgfunction.prototype.setFunction;
Emfgfunction.prototype.getLatex = function(){
// Get the function definition in latex. Localize the decimal separator, if needed.
result = this.latex;
if (this.parent.decimalperiod){
result = result.replace(/\./g,',');
}
return result;
}
Emfgfunction.prototype.setColor = function(color){
// Set the color of function graph.
var board = this.parent.board;
if (typeof(color) !== 'undefined'){
this.color = color;
} else {
this.color = this.color || 'blue';
}
if (board.elementsByName[this.name]) {
board.elementsByName[this.name].setProperty({strokeColor: this.color});
}
}
Emfgfunction.prototype.setMin = function(minimum){
// Set minimum of the range.
if (typeof(minimum) === 'undefined'){
minimum = '';
}
minimum = minimum.replace(/,/g,'.');
this.min = minimum;
if (minimum === ''){
return -Infinity;
}
var result = false;
try {
result = Emathfuncgraph.latexeval(minimum);
} catch (err){
result = false;
}
return result;
}
Emfgfunction.prototype.getMin = function(){
// Get minimum of the range.
var result;
try {
result = Emathfuncgraph.latexeval(this.min);
} catch (err){
result = -Infinity;
}
return result;
}
Emfgfunction.prototype.getMinLatex = function(){
// Get minimum of the range as Latex.
var result = this.min;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgfunction.prototype.setMax = function(maximum){
// Set maximum of the range.
if (typeof(maximum) === 'undefined'){
maximum = '';
}
maximum = maximum.replace(/,/g, '.');
this.max = maximum;
if (maximum === ''){
return Infinity;
}
var result = false;
try {
result = Emathfuncgraph.latexeval(maximum);
} catch (err){
result = false;
}
return result;
}
Emfgfunction.prototype.getMax = function(){
// Get maximum of the range.
var result;
try {
result = Emathfuncgraph.latexeval(this.max);
} catch (err){
result = Infinity;
}
return result;
}
Emfgfunction.prototype.getMaxLatex = function(){
// Get maximum of the range as Latex.
var result = this.max;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgfunction.prototype.getRange = function(){
// Get the range of function as LaTeX-string
var range = '';
var rbefore = '(';
var rafter = ')';
if (this.getMin() !== -Infinity){
rbefore += (this.getMinLatex() + ' \\lt ');
}
if (this.getMax() !== Infinity){
rafter = (' \\lt ' + this.getMaxLatex()) + rafter;
}
if (this.getMin() !== -Infinity || this.getMax() !== Infinity){
range = rbefore + 'x' + rafter;
}
return range;
}
Emfgfunction.prototype.isInvalid = function(){
// Check if Javascript of this function is invalid.
return this.js === 'INVALID';
}
Emfgfunction.prototype.getJessie = function(){
// Get the JessieScript string for this element.
var jessie = this.name + ':' + this.js +';';
return jessie;
}
Emfgfunction.prototype.getDrawOptions = function(){
// Get options that are used for drawing.
var element = this;
var result = {};
result.options = {
name: this.name,
fixed: this.isReadonly,
strokeWidth: 1.5,
strokeColor: this.color
};
result.drawtype = 'functiongraph';
var funcstring;
try {
funcstring = JXG.GeonextParser.geonext2JS(element.js);
} catch (err){
funcstring = '\'invalid expression\'';
}
result.parents = [
new Function('x','return (' + funcstring +');'),
(this.getMin()>-Infinity ? this.getMin(): null),
(this.getMax()<Infinity ? this.getMax() : null)
];
return [result];
}
Emfgfunction.prototype.getEditItem = function(){
// Return the html-string for this element's item in list in edit mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<a href="javascript:;" class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'"><span></span></a>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">'+ this.getLabel() + '=\\editable{' + this.getLatex() +'}</span>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'<a href="javascript:;" class="emfg_elemtools_removeelem emfg_gradbg"><span></span></a>',
'</div>',
'<div class="emfgitem_options emfg_function_options">',
'<div><span class="mathquill-editable" emfg-value="min" id="emfg_function_'+this.simplename+'_min" >'+ this.getMinLatex()+'</span>',
' < x < <span class="mathquill-editable" emfg-value="max" id="emfg_function_'+this.simplename+'_max" >'+this.getMaxLatex()+'</span></div>',
'</div>',
'<a href="javascript:;" class="emfg_options_showhide">...</a>',
].join('\n');
return elemsettings;
}
Emfgfunction.prototype.getInputData = function(){
// Get input data from mathquill elements.
var $mqelems = this.listitem.find('.mathquill-editable');
var data = $mqelems.mathquill('latex');
return data;
}
Emfgfunction.prototype.getShowItem = function(){
// Return the html-string for this element's item in list in show mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<span class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'">',
'<span></span></span>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">'+ this.getLabel() + '=' + this.getLatex() +'</span><div class="emfg_range"><span class="mathquill-embedded-latex">'+this.getRange()+'</span></div>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'</div>',
].join('\n');
return elemsettings;
}
Emfgfunction.prototype.initExtraOptions = function(){
// Init events for the extra options of this element.
var element = this;
this.listitem.find('.emfgitem_options #emfg_function_'+this.simplename+'_min, .emfgitem_options #emfg_function_'+this.simplename+'_max').bind('focusout.emfg', function(e){
var error = false;
var $mqelem = $(this);
var minmax = $mqelem.attr('emfg-value');
var latex = $mqelem.mathquill('latex');
var value;
switch (minmax) {
case 'min':
value = element.setMin(latex);
break;
case 'max':
value = element.setMax(latex);
break;
default:
break;
}
if (typeof(value) === 'number'){
$mqelem.removeClass('emfg_error');
element.changed();
element.redrawAll();
} else {
$mqelem.addClass('emfg_error');
}
});
}
/************************************************
* Emfgpoint -class
* Point elements in graph
************************************************/
var Emfgpoint = function(options){
// Representation of a point.
this.type = 'point';
this.name = options.name;
this.simplename = this.name.replace(/[{}]/g, '');
this.xcoordLatex = ''+options.xcoord || '0';
this.ycoordLatex = ''+options.ycoord || '0';
this.color = options.color || 'red';
this.readonly = !!options.readonly;
this.parent = options.parent;
this.setPoint({xcoord: this.xcoordLatex, ycoord: this.ycoordLatex});
}
// Inherit prototypes from Emfgelement, override constructor with own one.
Emfgpoint.prototype = new Emfgelement();
Emfgpoint.prototype.constructor = Emfgpoint;
Emfgpoint.prototype.getData = function(){
// Get all data of the point.
// Use the default fields defined in parent class and add some own fields.
var result = this.parentClass.getData.call(this);
result.xcoord = this.xcoordLatex;
result.ycoord = this.ycoordLatex;
return result;
}
Emfgpoint.prototype.setPoint = function(options){
// Set point's coordinates. Normalize decimal separator to '.'.
this.valid = true;
this.invalids = [];
this.xcoordLatex = (''+options.xcoord).replace(/,/g, '.');
this.ycoordLatex = (''+options.ycoord).replace(/,/g, '.');
try {
this.xcoord = Emathfuncgraph.latexeval(this.xcoordLatex);
} catch (err) {
this.valid = false;
this.invalids.push(0);
}
try {
this.ycoord = Emathfuncgraph.latexeval(this.ycoordLatex);
} catch (err) {
this.valid = false;
this.invalids.push(1);
}
return this.valid;
}
// Common alias for set-method.
Emfgpoint.prototype.setElement = Emfgpoint.prototype.setPoint;
Emfgpoint.prototype.getXstring = function(){
// Get xcoord as a Jessiescriptable string
return (''+(Math.round(this.xcoord * 10000000)/10000000));
}
Emfgpoint.prototype.getYstring = function(){
// Get ycoord as a Jessiescriptable string
return (''+(Math.round(this.ycoord * 10000000)/10000000));
}
Emfgpoint.prototype.getXlatex = function(){
// Get point's x-coordinate as LaTeX. Localize the decimal separator, if needed.
result = this.xcoordLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g,',');
}
return result;
}
Emfgpoint.prototype.getYlatex = function(){
// Get point's y-coordinate as LaTeX. Localize the decimal separator, if needed.
result = ''+this.ycoordLatex;
if (this.parent.decimalperiod){
result = result.replace('.',',');
}
return result;
}
Emfgpoint.prototype.setColor = function(color){
// Set the color of the point.
var board = this.parent.board;
if (typeof(color) !== 'undefined'){
this.color = color;
} else {
this.color = this.color || 'red';
}
board.elementsByName[this.name].setProperty({strokeColor: this.color, fillColor: this.color});
}
Emfgpoint.prototype.getJessie = function(){
// Get the JessieScript string for this element.
var jessie = this.name + '(' + this.xcoord + ',' + this.ycoord + '); ';
return jessie;
}
Emfgpoint.prototype.getDrawOptions = function(){
// Get options that are used for drawing.
var result = {};
result.options = {
name: this.name,
strokeColor: this.color,
fillColor: this.color,
fixed: this.readonly,
face: (this.readonly ? '[]' : 'o'),
strokeWidth: 1
};
result.drawtype = 'point';
result.parents = [this.xcoord, this.ycoord];
return [result];
}
Emfgpoint.prototype.getEditItem = function(){
// Return the html-string for this element's item in list in edit mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<a href="javascript:;" class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'"><span></span></a>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">' + this.getLabel() + '= \\left(\\editable{' + this.getXlatex() + '}\\:,\\:\\editable{'+ this.getYlatex() + '}'+'\\right)</span>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'<a href="javascript:;" class="emfg_elemtools_removeelem emfg_gradbg"><span></span></a>',
'</div>',
].join('\n');
return elemsettings;
}
Emfgpoint.prototype.getInputData = function(){
// Get input data from mathquill elements.
var $mqelems = this.listitem.find('.mathquill-editable');
var data = {
xcoord: $mqelems.eq(0).mathquill('latex'),
ycoord: $mqelems.eq(1).mathquill('latex')
}
return data;
}
Emfgpoint.prototype.getShowItem = function(){
// Return the html-string for this element's item in the list in show mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<span class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'">',
'<span></span></span>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">' + this.getLabel() + '= \\left('+ this.getXlatex() + '\\:,\\:' + this.getYlatex() + '\\right)</span>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'</div>',
].join('\n');
return elemsettings;
}
Emfgpoint.prototype.dragUpdate = function(){
// Update the point after dragging.
var board = this.parent.board;
var changed = false;
var jsxcoords = board.elementsByName[this.name].coords.usrCoords;
var coords = {xcoord: jsxcoords[1], ycoord: jsxcoords[2]};
if (coords.xcoord !== this.xcoord || coords.ycoord !== this.ycoord){
coords.xcoord = Math.round(coords.xcoord * 100) / 100;
coords.ycoord = Math.round(coords.ycoord * 100) / 100;
this.setPoint(coords);
changed = true;
}
return changed;
}
/************************************************
* Emfgsegment -class
* Segment elements between two points in graph
************************************************/
var Emfgsegment = function(options){
// Representation of a segment
this.type = 'segment';
this.name = options.name;
this.simplename = this.name.replace(/[{}]/g, '');
this.point1 = options.point1 || '';
this.point2 = options.point2 || '';
this.color = options.color || 'green';
this.readonly = options.readonly || false;
this.parent = options.parent;
this.showxdiff = options.showxdiff || false;
this.showydiff = options.showydiff || false;
this.showdxdyvalue = options.showdxdyvalue || false;
this.showlength = options.showlength || false;
}
// Inherit prototypes from Emfgelement, override constructor with own one.
Emfgsegment.prototype = new Emfgelement();
Emfgsegment.prototype.constructor = Emfgpoint;
Emfgsegment.prototype.getData = function(){
// Get all data of the segment.
// Use the default fields defined in parent class and add some own fields.
var result = this.parentClass.getData.call(this);
result.point1 = this.point1;
result.point2 = this.point2;
result.showxdiff = this.showxdiff;
result.showydiff = this.showydiff;
result.showdxdyvalue = this.showdxdyvalue;
result.showlength = this.showlength;
return result;
}
Emfgsegment.prototype.setSegment = function(options){
// Set the endpoints of segment.
this.valid = true;
this.invalids = [];
this.point1 = options.point1;
this.point2 = options.point2;
if (this.point1 === '' || !this.parent.board.elementsByName.hasOwnProperty(this.point1)){
this.valid = false;
this.invalids.push(0);
}
if (this.point2 === '' || !this.parent.board.elementsByName.hasOwnProperty(this.point2)){
this.valid = false;
this.invalids.push(1);
}
}
// Common alias for set-method.
Emfgsegment.prototype.setElement = Emfgsegment.prototype.setSegment;
Emfgsegment.prototype.showxdiff = function(onoff){
// Show or hide dx. (true or null == show, false == hide)
if (typeof(onoff) === 'undefined'){
onoff = true;
}
this.showxdiff = onoff;
}
Emfgsegment.prototype.showydiff = function(onoff){
// Show or hide dy. (true or null == show, false == hide)
if (typeof(onoff) === 'undefined'){
onoff = true;
}
this.showydiff = onoff;
}
Emfgsegment.prototype.getDeps = function(){
// Return the list of names of elements this element depends of.
// (Elements that are needed before this can be drawn.)
return [this.point1, this.point2];
}
Emfgsegment.prototype.setColor = function(color){
// Set the color of the segment.
var board = this.parent.board;
if (typeof(color) !== 'undefined'){
this.color = color;
} else {
this.color = this.color || 'green';
}
if (board.elementsByName[this.name]){
board.elementsByName[this.name].setProperty({strokeColor: this.color});
}
}
Emfgsegment.prototype.getJessie = function(){
// Get the JessieScript string for this element.
var jessie = this.name + '=[' + this.point1 + ' ' + this.point2 + ']; ';
if (this.showxdiff || this.showydiff){
jessie += this.name+'_hline=||('+this.point1+',horizontalline) invisible;';
jessie += this.name+'_vline=||('+this.point2+',verticalline) invisible;';
jessie += this.name+'_diff='+this.name+'_hline&'+this.name+'_vline invisible;'
}
if (this.showxdiff){
jessie += this.name+'_{dx}=['+this.point1+' '+this.name+'_diff] nolabel;';
jessie += this.name+'_{dxmid}=1/2('+this.point1+','+this.name+'_diff);';
}
if (this.showydiff){
jessie += this.name+'_{dy}=['+this.point2+' '+this.name+'_diff] nolabel;';
}
return jessie;
}
Emfgsegment.prototype.getDrawOptions = function(){
// Get options that are used for drawing. List of elements to draw.
var element = this;
var board = this.parent.board;
var resultlist = [
{
drawtype: 'line',
parents: [this.point1, this.point2],
options: {
straightFirst: false,
straightLast: false,
strokeColor: this.color,
name: this.name,
fixed: this.isReadonly(),
strokeWidth: 1.5
}
},
{
drawtype: 'parallel',
parents: ['horizontalline', this.point1],
options: {
name: this.name+'_hline',
visible: false
}
},
{
drawtype: 'parallel',
parents: ['verticalline', this.point2],
options: {
name: this.name+'_vline',
visible: false
}
},
{
drawtype: 'intersection',
parents: [this.name+'_hline', this.name+'_vline', 0],
options: {
name: this.name+'_diff',
visible: false
}
}
];
var p1 = board.elementsByName[this.point1];
var p2 = board.elementsByName[this.point2];
if (this.showxdiff){
resultlist.push({
drawtype: 'line',
parents: [this.point1, this.name+'_diff'],
options: {
name: this.name+'_{dx}',
straightFirst: false,
straightLast: false,
strokeColor: 'blue',
dash: 1,
strokeWidth: 1
}
});
resultlist.push({
drawtype: 'text',
parents: [
function(){return (p1.X() + p2.X())/2;},
function(){return (p1.Y() - 0.5);},
(this.showdxdyvalue ? function(){
var result = '\u0394<em>x</em>='+(Math.round(Math.abs(p1.X()-p2.X())*100)/100);
return (element.parent.decimalperiod ? result.replace(/\./g, ',') : result);
} : '\u0394<em>x</em>')
],
options: {color: 'blue'}
});
}
if (this.showydiff){
resultlist.push({
drawtype: 'line',
parents: [this.point2, this.name+'_diff'],
options: {
name: this.name+'_{dy}',
straightFirst: false,
straightLast: false,
strokeColor: 'blue',
dash: 1,
strokeWidth: 1
}
});
resultlist.push({
drawtype: 'text',
parents: [
function(){return (p2.X() + 0.5);},
function(){return (p1.Y() + p2.Y())/2;},
(this.showdxdyvalue ? function(){
var result = '\u0394<em>y</em>='+(Math.round(Math.abs(p1.Y()-p2.Y())*100)/100);
return (element.parent.decimalperiod ? result.replace(/\./g, ',') : result);
} : '\u0394<em>y</em>')
],
options: {color: 'blue'}
});
}
if (this.showlength) {
resultlist.push({
drawtype: 'text',
parents: [
function() {return (p1.X()+p2.X())/2 -0.5;},
function() {return (p1.Y()+p2.Y())/2 +0.5;},
function() {
var result = ''+Math.round(Math.sqrt(Math.pow(p1.X()-p2.X(), 2)+Math.pow(p1.Y()-p2.Y(), 2))*100)/100;
return (element.parent.decimalperiod ? result.replace(/\./g, ',') : result);
}
],
options: {color: 'blue', backgroundColor: 'white'}
});
}
return resultlist;
}
Emfgsegment.prototype.getEditItem = function(){
// Return the html-string for this element's item in the list in edit mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<a href="javascript:;" class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'"><span></span></a>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">' + this.getLabel() + '= \\: \\overline{\\editable{' + this.point1 + '} \\editable{'+ this.point2 + '}}</span>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'<a href="javascript:;" class="emfg_elemtools_removeelem emfg_gradbg"><span></span></a>',
'</div>',
'<div class="emfgitem_options emfg_segment_options">',
'<input type="checkbox"'+(this.showxdiff || this.showydiff ? ' checked="checked"':'')+' id="emfg_segment_'+this.simplename+'_dxdy" /><label for="emfg_segment_'+this.simplename+'_dxdy">Δx / Δy</label></br>',
'<input type="checkbox"'+(this.showdxdyvalue ? ' checked="checked"':'')+' id="emfg_segment_'+this.simplename+'_dxdyvalue" /><label for="emfg_segment_'+this.simplename+'_dxdyvalue">Δx=a / Δy=b</label><br />',
'<input type="checkbox"'+(this.showlength ? ' checked="checked"':'')+' id="emfg_segment_'+this.simplename+'_length" /><label for="emfg_segment_'+this.simplename+'_length">|s|</label>',
'</div>',
'<a href="javascript:;" class="emfg_options_showhide">...</a>',
].join('\n');
return elemsettings;
}
Emfgsegment.prototype.getInputData = function(){
// Get input data from mathquill elements.
var $mqelems = this.listitem.find('.mathquill-editable');
var data = {
point1: $mqelems.eq(0).mathquill('latex'),
point2: $mqelems.eq(1).mathquill('latex')
}
return data;
}
Emfgsegment.prototype.initExtraOptions = function(){
// Init events for the extra options of this element.
var element = this;
this.listitem.find('#emfg_segment_'+this.simplename+'_dxdy').change(function(){
element.showxdiff = $(this).is(':checked');
element.showydiff = element.showxdiff;
element.changed();
element.redrawAll();
});
this.listitem.find('#emfg_segment_'+this.simplename+'_dxdyvalue').change(function(){
element.showdxdyvalue = $(this).is(':checked');
element.changed();
element.redrawAll();
});
this.listitem.find('#emfg_segment_'+this.simplename+'_length').change(function(){
element.showlength = $(this).is(':checked');
element.changed();
element.redrawAll();
});
}
Emfgsegment.prototype.getShowItem = function(){
// Return the html-string for this element's item in the list in show mode.
var elemsettings = [
'<div class="emfg_elemtools">',
'<span class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'">',
'<span></span></span>',
'</div>',
'<div class="emfg_element_content">',
'<span class="mathquill-embedded-latex">' + this.getLabel() + ': \\: \\overline{' + this.point1 + '\\,'+ this.point2 +'}</span>',
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'</div>',
].join('\n');
return elemsettings;
}
/************************************************
* Emfgcircle -class
* Circle elements as equations in centerpoint mode or normal mode.
************************************************/
var Emfgcircle = function(options){
// Representation of a circle
this.type = 'circle';
this.parent = options.parent;
this.name = options.name;
this.simplename = this.name.replace(/[{}]/g, '');
this.inputtype = options.inputtype || 'centerpoint';
if (this.inputtype === 'centerpoint'){
this.x0Latex = ''+options.x0 || '0';
this.y0Latex = ''+options.y0 || '0';
this.rLatex = ''+options.r || '1';
this.convertToNormal();
} else if (this.inputtype === 'normal'){
this.aLatex = ''+options.a || '0';
this.bLatex = ''+options.b || '0';
this.cLatex = ''+options.c || '0';
}
this.color = options.color || 'red';
this.readonly = !!options.readonly;
this.valid = true;
this.invalids = [];
this.setCircle({x0: this.x0Latex, y0: this.y0Latex, r: this.rLatex});
}
// Inherit prototypes from Emfgelement, override constructor with own one.
Emfgcircle.prototype = new Emfgelement();
Emfgcircle.prototype.constructor = Emfgcircle;
Emfgcircle.prototype.getData = function(){
// Get all data of the circle.
// Use the default fields defined in parent class and add some own fields.
var result = this.parentClass.getData.call(this);
result.x0 = this.x0Latex;
result.y0 = this.y0Latex;
result.r = this.rLatex;
result.a = this.aLatex;
result.b = this.bLatex;
result.c = this.cLatex;
result.inputtype = this.inputtype;
return result;
}
Emfgcircle.prototype.setCircle = function(options){
// Set values for circle. Normalize decimal separator to '.'.
options = jQuery.extend(true,{
x0: this.x0Latex,
y0: this.y0Latex,
r: this.rLatex,
a: this.aLatex,
b: this.bLatex,
c: this.cLatex,
inputtype: this.inputtype
}, options);
this.valid = true;
if (options.inputtype === 'centerpoint'){
this.x0Latex = (''+options.x0).replace(/,/g, '.');
this.y0Latex = (''+options.y0).replace(/,/g, '.');
this.rLatex = (''+options.r).replace(/,/g, '.');
try {
this.x0 = Emathfuncgraph.latexeval(this.x0Latex);
} catch (err) {
this.valid = false;
this.invalids.push(0);
}
try {
this.y0 = Emathfuncgraph.latexeval(this.y0Latex);
} catch (err) {
this.valid = false;
this.invalids.push(1);
}
try {
this.r = Emathfuncgraph.latexeval(this.rLatex);
} catch (err) {
this.valid = false;
this.invalids.push(2);
}
if (this.valid){
this.convertToNormal();
}
} else if (options.inputtype === 'normal'){
this.aLatex = (''+options.a).replace(/,/g, '.');
this.bLatex = (''+options.b).replace(/,/g, '.');
this.cLatex = (''+options.c).replace(/,/g, '.');
try {
this.a = Emathfuncgraph.latexeval(this.aLatex);
} catch (err) {
this.valid = false;
this.invalids.push(0);
}
try {
this.b = Emathfuncgraph.latexeval(this.bLatex);
} catch (err) {
this.valid = false;
this.invalids.push(1);
}
try {
this.c = Emathfuncgraph.latexeval(this.cLatex);
} catch (err) {
this.valid = false;
this.invalids.push(2);
}
if (this.valid){
this.convertToCenterpoint();
}
}
return this.valid;
}
// Common alias for set-method.
Emfgcircle.prototype.setElement = Emfgcircle.prototype.setCircle;
Emfgcircle.prototype.getX0string = function(){
// Get x0 coordinate as a Jessiescriptable string.
return (''+(Math.round(this.x0 *10000000)/10000000));
}
Emfgcircle.prototype.getY0string = function(){
// Get y0 coordinate as a Jessiescriptable string.
return (''+(Math.round(this.y0 *10000000)/10000000));
}
Emfgcircle.prototype.getRstring = function(){
// Get value of r as a Jessiescriptable string.
return (''+(Math.round(this.r *10000000)/10000000));
}
Emfgcircle.prototype.getX0latex = function(){
// Get x0 coordinate as LaTeX. Localize the decimal separator, if needed.
result = this.x0Latex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgcircle.prototype.getY0latex = function(){
// Get y0 coordinate as LaTeX. Localize the decimal separator, if needed.
result = this.y0Latex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgcircle.prototype.getRlatex = function(){
// Get value of r as LaTeX. Localize the decimal separator, if needed.
result = this.rLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgcircle.prototype.getAlatex = function(){
// Get value of a as LaTeX. Localize the decimal separator, if needed.
result = this.aLatex;
if (this.parent.decimalperiod){
result = result.replace('.', ',');
}
return result;
}
Emfgcircle.prototype.getBlatex = function(){
// Get value of b as LaTeX. Localize the decimal separator, if needed.
result = this.bLatex;
if (this.parent.decimalperiod){
result = result.replace('.', ',');
}
return result;
}
Emfgcircle.prototype.getClatex = function(){
// Get value of c as LaTeX. Localize the decimal separator, if needed.
result = this.cLatex;
if (this.parent.decimalperiod){
result = result.replace('.', ',');
}
return result;
}
Emfgcircle.prototype.setColor = function(color){
// Set the color of the circle.
var board = this.parent.board;
if (typeof(color) !== 'undefined'){
this.color = color;
} else {
this.color = this.color || 'red';
}
board.elementsByName[this.name].setProperty({strokeColor: this.color});
board.elementsByName[this.name+'_{cp}'].setProperty({strokeColor: this.color});
}
Emfgcircle.prototype.getJessie = function(){
// Get the JessieScript string for this circle.
var jessie = [
'Cp'+this.name + '('+this.getX0string() +','+this.getY0string()+') invisible;',
this.name + '=k(Cp'+this.name+', '+this.getRstring()+');'
].join(' ');
return jessie;
}
Emfgcircle.prototype.getDrawOptions = function(){
// Get options that are used for drawing.
var resultlist = [
{
drawtype: 'point',
parents: [this.x0, this.y0],
options: {
name: this.name + '_{cp}',
face: (this.isReadonly() ? '[]' : 'x'),
withLabel: false,
size: 3,
strokeWidth: 1,
strokeColor: this.color,
fillColor: (this.isReadonly() ? 'white' : this.color),
fixed: this.readonly
}
},
{
drawtype: 'circle',
parents: [this.name+'_{cp}', this.r],
options: {
name: this.name,
strokeColor: this.color,
strokeWidth: 1.5,
withLabel: true
}
}
];
return resultlist;
}
Emfgcircle.prototype.getEditItem = function(){
// Return the html-string for this element's item in the list in edit mode.
var formulastrings = {
'centerpoint': '<span class="mathquill-embedded-latex" style="font-size: 85%; white-space: nowrap;">' + this.getLabel() + ':</span> <span class="mathquill-embedded-latex" style="font-size: 90%;"> \\left(x-\\left(\\editable{' + this.getX0latex() + '}\\right)\\right)^{2}+\\left(y-\\left(\\editable{'+ this.getY0latex() + '}\\right)\\right)^{2}=\\left(\\editable{'+this.getRlatex()+'}\\right)^{2}</span>',
'normal': '<span class="mathquill-embedded-latex" style="font-size: 85%; white-space: nowrap;">' + this.getLabel() + ':</span> <span class="mathquill-embedded-latex" style="font-size: 90%;"> x^2+y^2+\\left(\\editable{' + this.getAlatex() + '}\\right)x+\\left(\\editable{'+ this.getBlatex() + '}\\right)y+\\left(\\editable{'+this.getClatex()+'}\\right)=0</span>'
};
var elemsettings = [
'<div class="emfg_elemtools">',
'<a href="javascript:;" class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'"><span></span></a>',
'</div>',
'<div class="emfg_element_content">',
formulastrings[this.inputtype],
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'<a href="javascript:;" class="emfg_elemtools_removeelem emfg_gradbg"><span></span></a>',
'</div>',
'<div class="emfgitem_options emfg_circle_options">',
'<input type="radio"'+(this.inputtype === 'centerpoint' ? ' checked="checked"':'')+' id="emfg_circle_'+this.name+'_inputtypecp" name="emfg_circle_'+this.name+'_inputtype" value="centerpoint" /><label for="emfg_circle_'+this.name+'_inputtypecp"><i>(x-x<sub>0</sub>)<sup>2</sup>+(y-y<sub>0</sub>)<sup>2</sup>=r<sup>2</sup></i></label><br />',
'<input type="radio"'+(this.inputtype === 'normal' ? ' checked="checked"':'')+' id="emfg_circle_'+this.name+'_inputtypenormal" name="emfg_circle_'+this.name+'_inputtype" value="normal" /><label for="emfg_circle_'+this.name+'_inputtypenormal"><i>x<sup>2</sup>+y<sup>2</sup>+ax+by+c=0</i></label>',
'</div>',
'<a href="javascript:;" class="emfg_options_showhide">...</a>',
].join('\n');
return elemsettings;
}
Emfgcircle.prototype.initExtraOptions = function(){
// Init events for the extra options of this element.
var element = this;
this.listitem.find('input[name="emfg_circle_'+this.name+'_inputtype"]').change(function(){
element.inputtype = $(this).val();
element.changed();
element.drawEditItem();
element.listitem.find('.emfgitem_options').show().next().addClass('open');
});
}
Emfgcircle.prototype.getInputData = function(){
// Get input data from mathquill elements.
var element = this;
var $mqelems = this.listitem.find('.mathquill-editable');
var data = {inputtype: this.inputtype};
if (element.inputtype === 'centerpoint'){
data.x0 = $mqelems.eq(0).mathquill('latex');
data.y0 = $mqelems.eq(1).mathquill('latex');
data.r = $mqelems.eq(2).mathquill('latex');
} else {
data.a = $mqelems.eq(0).mathquill('latex');
data.b = $mqelems.eq(1).mathquill('latex');
data.c = $mqelems.eq(2).mathquill('latex');
}
return data;
}
Emfgcircle.prototype.getShowItem = function(){
// Return the html-string for this element's item in the list in show mode.
var formulastrings = {
'centerpoint': '<span class="mathquill-embedded-latex" style="font-size: 85%; white-space: nowrap;">' + this.getLabel() + ':</span> <span class="mathquill-embedded-latex" style="font-size: 90%;"> \\left(x-\\left(' + this.getX0latex() + '\\right)\\right)^{2}+\\left(y-\\left('+ this.getY0latex() + '\\right)\\right)^{2}=\\left('+this.getRlatex()+'\\right)^{2}</span>',
'normal': '<span class="mathquill-embedded-latex" style="font-size: 85%; white-space: nowrap;">' + this.getLabel() + ':</span> <span class="mathquill-embedded-latex" style="font-size: 90%;"> x^2+y^2+\\left(' + this.getAlatex() + '\\right)x+\\left('+ this.getBlatex() + '\\right)y+\\left('+this.getClatex()+'\\right)=0</span>'
};
var elemsettings = [
'<div class="emfg_elemtools">',
'<span class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'">',
'<span></span></span>',
'</div>',
'<div class="emfg_element_content">',
formulastrings[this.inputtype],
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'</div>',
].join('\n');
return elemsettings;
}
Emfgcircle.prototype.convertToNormal = function(){
// Compute coefficients for normal form, when centerpoint format is known;
this.a = Math.round(-2*this.x0 * 10)/10;
this.b = Math.round(-2*this.y0 * 10)/10;
this.c = Math.round((this.x0 * this.x0 + this.y0 * this.y0 - (this.r * this.r)) * 10 )/10;
this.aLatex = ''+this.a;
this.bLatex = ''+this.b;
this.cLatex = ''+this.c;
}
Emfgcircle.prototype.convertToCenterpoint = function(){
// Compute coefficients for centerpoint format, when normal form is known;
this.x0 = this.a / (-2);
this.y0 = this.b / (-2);
this.r = Math.round(Math.sqrt(this.x0 * this.x0 + this.y0 * this.y0 - this.c)*10)/10;
this.x0Latex = ''+this.x0;
this.y0Latex = ''+this.y0;
this.rLatex = ''+this.r;
}
Emfgcircle.prototype.dragUpdate = function(){
// Update dragged circle.
var board = this.parent.board;
var changed = false;
var jsxcoords = board.elementsByName[this.name + '_{cp}'].coords.usrCoords;
var coords = {x0: jsxcoords[1], y0: jsxcoords[2]};
if (coords.x0 !== this.x0 || coords.y0 !== this.y0){
coords.x0 = Math.round(coords.x0 * 10)/10;
coords.y0 = Math.round(coords.y0 * 10)/10;
coords.inputtype = 'centerpoint';
this.setCircle(coords);
changed = true;
}
return changed;
}
/************************************************
* Emfgline -class
* Line elements as equations.
************************************************/
var Emfgline = function(options){
// Representation of a line.
this.type = 'line';
this.parent = options.parent;
this.name = options.name;
this.simplename = this.name.replace(/[{}]/g, '');
this.inputtype = options.inputtype || 'explicit';
this.color = options.color || 'blue';
this.readonly = !! options.readonly;
this.valid = true;
this.invalids = [];
switch (this.inputtype){
case 'explicit':
this.kLatex = ''+options.k || '1';
this.ebLatex = ''+options.eb || '0';
this.setLine();
this.convertFromExplicit();
break;
case 'normal':
this.aLatex = ''+options.a || '1';
this.bLatex = ''+options.b || '1';
this.cLatex = ''+options.c || '0';
this.setLine();
this.convertFromNormal();
break;
case 'point':
this.kLatex = ''+options.k || '1';
this.x0Latex = ''+options.x0 || '0';
this.y0Latex = ''+options.y0 || '0';
this.setLine();
this.convertFromPoint();
break;
case 'vertical':
this.vaLatex = ''+options.va || '0';
this.setLine();
this.convertFromVertical();
break;
default:
this.setLine();
break;
}
}
// Inherit prototypes from Emfgelement, override constructor with own one.
Emfgline.prototype = new Emfgelement();
Emfgline.prototype.constructor = Emfgline;
Emfgline.prototype.getData = function(){
// Get all data of the line.
// Use the default fields defined in parent class and add some own fields.
var result = this.parentClass.getData.call(this);
result.k = this.kLatex;
result.eb = this.ebLatex;
result.a = this.aLatex;
result.b = this.bLatex;
result.c = this.cLatex;
result.x0 = this.x0Latex;
result.y0 = this.y0Latex;
result.va = this.vaLatex;
result.inputtype = this.inputtype;
return result;
}
Emfgline.prototype.setLine = function(options){
// Set values for line. Normalize decimal separator to '.'.
options = jQuery.extend(true,{
k: this.kLatex,
eb: this.ebLatex,
a: this.aLatex,
b: this.bLatex,
c: this.cLatex,
x0: this.x0Latex,
y0: this.y0Latex,
va: this.vaLatex,
inputtype: this.inputtype
}, options);
this.valid = true;
this.invalids = [];
switch (options.inputtype){
case 'normal':
this.aLatex = (''+options.a).replace(/,/g, '.');
this.bLatex = (''+options.b).replace(/,/g, '.');
this.cLatex = (''+options.c).replace(/,/g, '.');
try {
this.a = Emathfuncgraph.latexeval(this.aLatex);
} catch (err){
this.valid = false;
this.invalids.push(0);
}
try {
this.b = Emathfuncgraph.latexeval(this.bLatex);
} catch (err){
this.valid = false;
this.invalids.push(1);
}
try {
this.c = Emathfuncgraph.latexeval(this.cLatex);
} catch (err){
this.valid = false;
this.invalids.push(2);
}
if (this.valid){
this.convertFromNormal();
}
break;
case 'explicit':
this.kLatex = (''+options.k).replace(/,/g, '.');
this.ebLatex = (''+options.eb).replace(/,/g, '.');
try {
this.k = Emathfuncgraph.latexeval(this.kLatex);
} catch (err){
this.valid = false;
this.invalids.push(0);
}
try {
this.eb = Emathfuncgraph.latexeval(this.ebLatex);
} catch (err){
this.valid = false;
this.invalids.push(1);
}
if (this.valid){
this.convertFromExplicit();
}
break;
case 'point':
this.y0Latex = (''+options.y0).replace(/,/g, '.');
this.kLatex = (''+options.k).replace(/,/g, '.');
this.x0Latex = (''+options.x0).replace(/,/g, '.');
try {
this.y0 = Emathfuncgraph.latexeval(this.y0Latex);
} catch (err){
this.valid = false;
this.invalids.push(0);
}
try {
this.k = Emathfuncgraph.latexeval(this.kLatex);
} catch (err){
this.valid = false;
this.invalids.push(1);
}
try {
this.x0 = Emathfuncgraph.latexeval(this.x0Latex);
} catch (err){
this.valid = false;
this.invalids.push(2);
}
if (this.valid){
this.convertFromPoint();
}
break;
case 'vertical':
this.vaLatex = (''+options.va).replace(/,/g, '.');
try {
this.va = Emathfuncgraph.latexeval(this.vaLatex);
} catch (err){
this.valid = false;
this.invalids.push(0);
}
if (this.valid){
this.convertFromVertical();
}
break;
default:
break;
}
}
// Common alias for set-method.
Emfgline.prototype.setElement = Emfgline.prototype.setLine;
Emfgline.prototype.getAString = function(){
// Get a as a string.
return (''+(Math.round(this.a * 10000000)/10000000));
}
Emfgline.prototype.getALatex = function(){
// Get a as LaTeX. Localize the decimal separator, if needed.
result = this.aLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getBString = function(){
// Get b as a string.
return (''+(Math.round(this.b * 10000000)/10000000));
}
Emfgline.prototype.getBLatex = function(){
// Get b as LaTeX. Localize the decimal separator, if needed.
result = this.bLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getCString = function(){
// Get c as a string.
return (''+(Math.round(this.c * 10000000)/10000000));
}
Emfgline.prototype.getCLatex = function(){
// Get c as LaTeX. Localize the decimal separator, if needed.
result = this.cLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getKString = function(){
// Get k as a string.
return (''+(Math.round(this.k * 10000000)/10000000));
}
Emfgline.prototype.getKLatex = function(){
// Get k as LaTeX. Localize the decimal separator, if needed.
result = this.kLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getEbString = function(){
// Get eb as a string.
return (''+(Math.round(this.eb * 10000000)/10000000));
}
Emfgline.prototype.getEbLatex = function(){
// Get eb as LaTeX. Localize the decimal separator, if needed.
result = this.ebLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getX0String = function(){
// Get x0 as a string.
return (''+(Math.round(this.x0 * 10000000)/10000000));
}
Emfgline.prototype.getX0Latex = function(){
// Get x0 as LaTeX. Localize the decimal separator, if needed.
result = this.x0Latex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getY0String = function(){
// Get y0 as a string.
return (''+(Math.round(this.y0 * 10000000)/10000000));
}
Emfgline.prototype.getY0Latex = function(){
// Get y0 as LaTeX. Localize the decimal separator, if needed.
result = this.y0Latex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.getVaString = function(){
// Get va as a string.
return (''+(Math.round(this.va * 10000000)/10000000));
}
Emfgline.prototype.getVaLatex = function(){
// Get va as LaTeX. Localize the decimal separator, if needed.
result = this.vaLatex;
if (this.parent.decimalperiod){
result = result.replace(/\./g, ',');
}
return result;
}
Emfgline.prototype.setColor = function(color){
// Set the color of the line.
var board = this.parent.board;
if (typeof(color) !== 'undefined'){
this.color = color;
} else {
this.color = this.color || 'blue';
}
board.elementsByName[this.name].setProperty({strokeColor: this.color});
}
Emfgline.prototype.getDrawOptions = function(){
// Get options that are used for drawing.
var element = this;
var result = {};
result.drawtype = 'line';
result.parents = [this.c, this.a, this.b];
result.options = {
name: this.name,
strokeWidth: 1.5,
strokeColor: this.color,
fixed: true
}
return [result];
}
Emfgline.prototype.getEditItem = function(){
// Return the html-string for this element's item in the list in edit mode.
var formulastrings = {
'normal': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">\\editable{' +this.getALatex()+ '}x+\\left(\\editable{' + this.getBLatex() + '}\\right)y+\\left(\\editable{' + this.getCLatex() + '}\\right)=0</span>',
'explicit': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">y=\\editable{' +this.getKLatex()+ '}x+\\left(\\editable{' + this.getEbLatex() + '}\\right)</span>',
'point': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">y-\\left(\\editable{' +this.getY0Latex()+ '}\\right)=\\editable{'+this.getKLatex()+'}\\cdot \\left(x-\\left(\\editable{' + this.getX0Latex() + '}\\right)\\right)</span>',
'vertical': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">x=\\editable{' +this.getVaLatex()+ '}</span>'
};
var elemsettings = [
'<div class="emfg_elemtools">',
'<a href="javascript:;" class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'"><span></span></a>',
'</div>',
'<div class="emfg_element_content">',
formulastrings[this.inputtype],
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'<a href="javascript:;" class="emfg_elemtools_removeelem emfg_gradbg"><span></span></a>',
'</div>',
'<div class="emfgitem_options emfg_circle_options">',
'<input type="radio"'+(this.inputtype === 'normal' ? ' checked="checked"':'')+' id="emfg_line_'+this.name+'_inputtypenormal" name="emfg_line_'+this.name+'_inputtype" value="normal" /><label for="emfg_line_'+this.name+'_inputtypenormal"><i>ax+by+c=0</i></label><br />',
'<input type="radio"'+(this.inputtype === 'explicit' ? ' checked="checked"':'')+' id="emfg_line_'+this.name+'_inputtypeexplicit" name="emfg_line_'+this.name+'_inputtype" value="explicit" /><label for="emfg_line_'+this.name+'_inputtypeexplicit"><i>y=kx+b</i></label><br />',
'<input type="radio"'+(this.inputtype === 'point' ? ' checked="checked"':'')+' id="emfg_line_'+this.name+'_inputtypepoint" name="emfg_line_'+this.name+'_inputtype" value="point" /><label for="emfg_line_'+this.name+'_inputtypepoint"><i>y-y<sub>0</sub>=k(x-x<sub>0</sub>)</i></label><br />',
'<input type="radio"'+(this.inputtype === 'vertical' ? ' checked="checked"':'')+' id="emfg_line_'+this.name+'_inputtypevertical" name="emfg_line_'+this.name+'_inputtype" value="vertical" /><label for="emfg_line_'+this.name+'_inputtypevertical"><i>x=a</i></label>',
'</div>',
'<a href="javascript:;" class="emfg_options_showhide">...</a>',
].join('\n');
return elemsettings;
}
Emfgline.prototype.getInputData = function(){
// Get input data from mathquill elements.
var $mqelems = this.listitem.find('.mathquill-editable');
var data = {inputtype: this.inputtype};
switch (this.inputtype){
case 'normal':
data.a = $mqelems.eq(0).mathquill('latex');
data.b = $mqelems.eq(1).mathquill('latex');
data.c = $mqelems.eq(2).mathquill('latex');
break;
case 'explicit':
data.k = $mqelems.eq(0).mathquill('latex');
data.eb = $mqelems.eq(1).mathquill('latex');
break;
case 'point':
data.y0 = $mqelems.eq(0).mathquill('latex');
data.k = $mqelems.eq(1).mathquill('latex');
data.x0 = $mqelems.eq(2).mathquill('latex');
break;
case 'vertical':
data.va = $mqelems.eq(0).mathquill('latex');
break;
default:
break;
}
return data;
}
Emfgline.prototype.initExtraOptions = function(){
// Init events for the extra options of this element.
var element = this;
this.listitem.find('input[name="emfg_line_'+this.name+'_inputtype"]').change(function(){
element.inputtype = $(this).val();
switch (element.inputtype){
case 'explicit':
element.convertFromExplicit();
break;
case 'point':
element.convertFromPoint();
break;
case 'vertical':
element.convertFromVertical();
break;
default:
element.convertFromNormal();
break;
}
element.changed();
element.drawEditItem();
//element.updateFromInput();
//element.markErrors();
element.redrawAll();
element.listitem.find('.emfgitem_options').show().next().addClass('open');
});
}
Emfgline.prototype.getShowItem = function(){
// Return the html-string for this element's item in list in show mode.
var formulastrings = {
'normal': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">' +this.getALatex()+ 'x+\\left(' + this.getBLatex() + '\\right)y+\\left(' + this.getCLatex() + '\\right)=0</span>',
'explicit': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">y=' +this.getKLatex()+ ' x+\\left(' + this.getEbLatex() + '\\right)</span>',
'point': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">y-\\left(' +this.getY0Latex()+ '\\right)='+this.getKLatex()+'\\cdot \\left(x-\\left(' + this.getX0Latex() + '\\right)\\right)</span>',
'vertical': '<span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">'+this.getLabel() + ': </span> <span class="mathquill-embedded-latex" style="font-size: 90%; white-space: nowrap;">x=' +this.getVaLatex()+ '</span>'
};
var elemsettings = [
'<div class="emfg_elemtools">',
'<span class="emfg_elemtools_color emfg_gradbg" color="'+this.getColor()+'">',
'<span></span></span>',
'</div>',
'<div class="emfg_element_content">',
formulastrings[this.inputtype],
'</div>',
'<div class="emfg_elemtools_right">',
this.lockHtml(this.parent.authormode),
'</div>',
].join('\n');
return elemsettings;
}
Emfgline.prototype.markErrors = function(){
var $mqelems = this.listitem.find('.mathquill-editable');
if (!this.valid){
for (var i = 0; i < this.invalids.length; i++){
$mqelems.eq(this.invalids[i]).addClass('emfg_error');
}
} else {
$mqelems.removeClass('emfg_error');
}
}
Emfgline.prototype.convertFromNormal = function(){
// Compute coefficients for other types from normal.
this.convertFromNormalToExplicit();
this.convertFromNormalToVertical();
this.convertFromNormalToPoint();
}
Emfgline.prototype.convertFromNormalToExplicit = function(frompoint){
// Compute coefficients for explicit format from normal.
if (this.b !== 0){
if (!frompoint){
this.k = Math.round(-10*this.a/this.b)/10;
}
this.eb = Math.round(-10*this.c/this.b)/10;
} else {
if (!frompoint){
this.k = 1;
}
this.eb = 0;
}
if (!frompoint){
this.kLatex = ''+this.k;
}
this.ebLatex = ''+this.eb;
}
Emfgline.prototype.convertFromNormalToVertical = function(){
// Compute coefficients for vertical line from normal form.
if (this.a !== 0){
this.va = Math.round(-10*this.c/this.a)/10;
} else {
this.va = 0;
}
this.vaLatex = ''+this.va;
}
Emfgline.prototype.convertFromNormalToPoint = function(fromexplicit){
// Compute coefficients for point-on-line format from normal form.
if (this.a !== 0 && this.b !== 0){
this.y0 = 0;
this.x0 = Math.round(-10*this.c/this.a)/10;
if (!fromexplicit){
this.k = Math.round(-10*this.a/this.b)/10;
}
} else {
this.y0 = 0;
this.x0 = 0;
if (!fromexplicit){
this.k = 1;
}
}
if (!fromexplicit){
this.kLatex = ''+this.k;
}
this.x0Latex = ''+this.x0;
this.y0Latex = ''+this.y0;
}
Emfgline.prototype.convertFromExplicit = function(){
// Compute coefficients for other types from explicit.
this.a = Math.round(10*this.k)/10;
this.b = -1;
this.c = Math.round(10*this.eb)/10;
this.aLatex = ''+this.a;
this.bLatex = ''+this.b;
this.cLatex = ''+this.c;
this.convertFromNormalToVertical();
this.convertFromNormalToPoint(true);
}
Emfgline.prototype.convertFromPoint = function(){
// Compute coefficients for other types from point.
this.a = this.k;
this.b = -1;
this.c = Math.round(10*(this.y0 - this.k * this.x0))/10;
this.aLatex = ''+this.kLatex;
this.bLatex = ''+this.b;
this.cLatex = ''+this.c;
this.convertFromNormalToExplicit(true);
this.convertFromNormalToVertical();
}
Emfgline.prototype.convertFromVertical = function(){
// Compute coefficients for other types from vertical.
this.a = 1;
this.b = 0;
this.c = -this.va;
this.aLatex = ''+this.a;
this.bLatex = ''+this.b;
this.cLatex = ''+this.c;
this.convertFromNormalToExplicit();
this.convertFromNormalToPoint();
}
})(jQuery)
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.emathfuncgraph = {
/******************************
* Show emathfuncgraph
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('Missing funcgraph.', place);
return false;
}
var thispage = jQuery(place).parents('.bookpage');
if (thispage.length > 0){
var pageno = Math.max(jQuery('#pageOne, #pageTwo').index(thispage), 0);
} else {
var pageno = 0;
}
var periodcountries = ['et','fi','sv'];
periodcountries.indexOf(EbookPages[pageno].ebook.curriculum) != -1;
var funcgraphid = params[0];
var isauthor = (params[1] === 'author' || params[1] === 'authordialog');
var iseditable = (params[1] === 'edit');// || isauthor);
var isviewmode = (params[1] === 'view');
var emfgtext = '{{emathfg emathfg_'+funcgraphid+'{\n}}}';
wikify(emfgtext, place);
if (tiddler) {
var settings = jQuery.extend(true, {},DataTiddler.getData(tiddler, 'emathfuncgraph',{}));
} else {
var settings = {};
}
settings[funcgraphid] = settings[funcgraphid] || {};
settings[funcgraphid].editable = iseditable || (!isviewmode && settings[funcgraphid].editable);
//settings[funcgraphid].editable = iseditable;
settings[funcgraphid].authormode = isauthor;
settings[funcgraphid].decimalperiod = (periodcountries.indexOf(EbookPages[pageno].ebook.curriculum) !== -1);
var fgraph = jQuery(place).find('.emathfg.emathfg_'+funcgraphid).last().emathfuncgraph(settings[funcgraphid])
if ((iseditable || isauthor) && params[1] !== 'authordialog') {
fgraph.unbind('emathfuncgraph_changed').bind('emathfuncgraph_changed', function(e){
var $emfgplace = jQuery(this);
var data = $emfgplace.emathfuncgraph('get');
var settings = DataTiddler.getData(tiddler, 'emathfuncgraph',{});
settings[funcgraphid] = data;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tiddler.setData('emathfuncgraph', settings);
config.options.chkAutoSave = autosavestatus;
});
}
return true;
}
}
}
//}}}
/***
|Name|GeEditor|
|Version|1.0|
|Author|Rolf Lindén (rolind@utu.fi) + Petri Salmela (pesasa@iki.fi)|
|License|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, JSXGraph 0.95 or newer, MathQuill.|
|Description|Creates and shows geometric scenes constructed from geometric primitives.|
!!!!!Revisions
<<<
20131223.1722 ''Version 1.0''
* Swedish translation
* Moving translations in the file
<<<
<<<
20131218.2259 ''Version 0.6''
* Enable colorpicker
* Small fix on point move.
<<<
<<<
20131218.1525 ''Version 0.5''
* New tools: parallelogram, bisector, tangent, parallel, text label
* Small fixes
* Move and zoom scene
<<<
<<<
20131212.1659 ''Version 0.4''
* Midpoint tool.
<<<
<<<
20131211.1032 ''Version 0.3''
* Right triangle, rectangle, remove animation from advanced properties
* Fix Rcircle, when clicking sides of right triangles or rectangles.
<<<
<<<
20131209.1207 ''Version 0.2''
* More objecttypes
<<<
<<<
20131203.1552 ''Version 0.1''
* First version with TiddlyWiki-macro
<<<
<<<
20131105.1435 ''Version 0.01''
* Started rewrite
<<<
!!!!!Code
***/
//{{{
/**
* Geometry editor (jQuery plugin).
* gedit.js
* jQuery-plugin for creating geometrical constructions
* Created by: E-Math -project ( http://emath.eu )
* Petri Salmela
* Petri Sallasmaa
* 2012-2013
* v.1.0
* Copyright: Four Ferries oy
* http://fourferries.fi
* License: GNU AGPL
**/
(function ($) {
{ /*** jQuery plugin ***/
$.fn.geditor = function(options){
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on Geditor' );
return this;
}
}
var methods = {
init: function(params){
params = $.extend(true, {
'editable' : true,
'width' : '100%',
'height' : '500px',
'mode' : 'free',
'isSquare' : false,
'browsingMode' : 'tabs',
'scenes' :
[
{
'type': 'Scene',
'name': '',
'objects': [],
'boundingBox': [-10,5,10,-5],
'description' : '',
'allowControls' : true,
'showAxes' : true,
'showGrid': false,
'isStatic': false
}
]
}, params);
var editor = new GEditor(this, params);
editor.init();
},
getdata: function(params){
var $place = $(this);
$place.trigger('getdata');
var data = $place.data('[[geoeditordata]]');
return data;
}
}
}
{ /*** Editor class ***/
/******
* Class for GEditor.
******/
var GEditor = function(place, options){
options = $.extend({
editable: false,
scenes: [],
width: 500,
height: 500,
browsingMode: 'tabs',
lang: $(place).closest('[lang]').attr('lang') || 'en'
}, options);
var editor = this;
this.place = $(place);
this.lang = options.lang;
this.localizer = new Localizer(this.lang);
this.decimalperiod = this.localizer.decimalperiod();
this.editable = options.editable;
this.dataObj = options.scenes;
this.width = options.width;
this.height = options.height;
this.browsingMode = options.browsingMode;
this.place.addClass('geoeditorwrapper gedit-gradbg');
this.sceneArr = [];
this.sceneById = {};
this.boxnum = this.generateId('geditorbox');
this.objIdStore = {};
this.generateSceneArr();
this.sceneNum = 0;
this.objectId = 'scene';
$(window).resize(function() { editor.updateView(); });
}
/******
* Container for GeoTool constructors
******/
GEditor.prototype.geotools = [];
/******
* Init the viewing area.
******/
GEditor.prototype.init = function(){
if ($('head style#geditorstyle').length == 0){
$('head').append('<style id="geditorstyle" type="text/css">'+GEditor.strings.css+'</style>');
}
this.place.html(this.getLayout());
this.layout = {
scenearea: this.place.find('.gedit-scenearea'),
naviarea: this.place.find('.gedit-naviarea'),
objectarea: this.place.find('.gedit-objectarea'),
objectlist: this.place.find('.gedit-objectlist'),
propertyarea: this.place.find('.gedit-propertyarea'),
tabarea: this.place.find('.gedit-tabarea'),
toolarea: this.place.find('.gedit-toolarea'),
subtoolarea: this.place.find('.gedit-subtoolarea'),
infoarea: this.place.find('.gedit-infoarea')
}
this.layout.scenearea.attr('id', 'geditorbox-'+this.boxnum);
this.initNavi();
// If select tool is inited in view-mode, the state of scene is remembered
// between scene changes.
this.initTools();
this.setClasses();
this.addHandlers();
this.setScene(0);
}
/******
* Get data
******/
GEditor.prototype.getData = function(){
var data = {
editable: this.editable,
width: this.width,
height: this.height,
mode: this.mode,
isSquare: this.isSquare,
browsingMode: this.browsingMode,
scenes: []
}
for (var i = 0; i < this.sceneArr.length; i++) {
data.scenes.push(this.sceneArr[i].getData());
}
return data;
}
/******
* Init tools
******/
GEditor.prototype.initTools = function(){
this.tools = {};
var toolList = [];
for (var i = 0; i < this.geotools.length; i++) {
var tool = new this.geotools[i](this);
var toolType = tool.getType();
this.tools[toolType] = tool;
if (!tool.subtool) {
toolList.push('<li class="gedit-geotool" data-gedit-geotooltype="'+toolType+'" title="'+this.localize(toolType + '-maintooltip')+'">'+tool.getIcon()+'<div class="gedit-toolshade"></div></li>');
}
}
this.layout.toolarea.html(toolList.join('\n'));
this.selectTool('Select');
}
/******
* Init navigation
******/
GEditor.prototype.initNavi = function(){
this.layout.naviarea.html(GEditor.strings.tools.navigation);
}
/******
* Generate unique number for html-index with given prefix.
******/
GEditor.prototype.generateId = function(prefix){
var idnum = 0;
while ($('#' + prefix + '-' + idnum).length > 0) {
idnum++;
}
return idnum;
}
/******
* Generate unique object id for object of given type.
******/
GEditor.prototype.getObjId = function(objType){
if (typeof(this.objIdStore[objType]) === 'undefined') {
this.objIdStore[objType] = 0;
}
while (objType !== 'Scene' && this.sceneArr[this.sceneNum].hasObject('Geo'+objType+'_{'+this.objIdStore[objType]+'}')){
this.objIdStore[objType]++;
}
var objId = 'Geo' + objType + '_{' + this.objIdStore[objType]++ +'}';
return objId;
}
/**
* Return name of object with given geoid in current scene.
*/
GEditor.prototype.getObjName = function(geoid){
return this.sceneArr[this.sceneNum].getObjName(geoid);
}
/******
* Get layout depending on view/edit -mode.
******/
GEditor.prototype.getLayout = function(){
if (this.editable) {
return GEditor.templates.editorlayout;
} else {
return GEditor.templates.viewlayout;
}
}
/******
* Set classes by mode.
******/
GEditor.prototype.setClasses = function(){
this.place.removeClass('editmode viewmode');
if (this.editable) {
this.place.addClass('editmode');
} else {
this.place.addClass('viewmode');
}
}
/******
* Generate the sceneArr from the data.
******/
GEditor.prototype.generateSceneArr = function(){
this.sceneArr = [];
this.sceneById = {};
if (this.dataObj != null) {
for (var i = 0; i < this.dataObj.length; ++i) {
this.addScene(this.dataObj[i]);
}
}
}
/******
* Add new scene
******/
GEditor.prototype.addScene = function(data){
data.decimalperiod = this.decimalperiod;
data.geoid = this.getObjId(data.type);
var newscene = new GeoScene(data);
this.sceneArr.push(newscene);
this.sceneById[newscene.geoid] = newscene;
}
/******
* Remove scene
******/
GEditor.prototype.removeScene = function(sceneNum){
if (typeof(sceneNum) === 'undefined') {
sceneNum = this.sceneNum;
}
if (sceneNum >= 0 && sceneNum < this.sceneArr.length) {
if (this.sceneArr.length === 1) {
var oldscene = this.sceneArr[this.sceneNum].getData();
var scenedata = {type: 'Scene', boundingBox: oldscene.boundingBox, showGrid: oldscene.showGrid};
this.addScene(scenedata);
}
this.sceneArr.splice(sceneNum, 1);
this.sceneNum = Math.min(this.sceneNum, this.sceneArr.length - 1);
this.updateAll();
}
}
/******
* Set scene active
******/
GEditor.prototype.setScene = function(sceneNum){
this.sceneNum = sceneNum;
this.objectId = 'scene';
this.updateAll();
}
/******
* Set next scene active
******/
GEditor.prototype.nextScene = function(){
this.sceneNum = (this.sceneNum + 1) % this.sceneArr.length;
this.objectId = 'scene';
this.updateAll();
}
/******
* Set next scene active
******/
GEditor.prototype.previousScene = function(){
this.sceneNum = (this.sceneNum - 1 + this.sceneArr.length) % this.sceneArr.length;
this.objectId = 'scene';
this.updateAll();
}
/******
* Add handlers for events.
******/
GEditor.prototype.addHandlers = function(){
var editor = this;
this.place.bind('getdata', function(event){
var data = editor.getData();
editor.place.data('[[geoeditordata]]', data);
});
this.place.bind('updateview', function(event){
editor.updateView();
});
this.place.bind('updatefromdialog', function(event){
editor.updateDataFromDialog();
});
this.place.bind('updateinfo', function(event, message){
editor.updateInfo(message);
});
this.addHandlersTab();
this.addHandlersView();
this.addHandlersNavi();
if (this.editable) {
this.addHandlersObjlist();
this.addHandlersProplist();
this.addHandlersTool();
this.addHandlersAction();
}
}
/******
* Add handlers for tab-events.
******/
GEditor.prototype.addHandlersTab = function(){
/*** Tab actions *********/
var editor = this;
this.place.delegate('ul.gedit-tabarea li.gedit-tab[data-gedit-scenenum]', 'click', function(event){
var tab = $(this);
var newscene = parseInt(tab.attr('data-gedit-scenenum'));
editor.setScene(newscene);
});
this.place.delegate('ul.gedit-tabarea li.gedit-tabnext', 'click', function(event){
editor.nextScene();
});
this.place.delegate('ul.gedit-tabarea li.gedit-tabprev', 'click', function(event){
editor.previousScene();
});
this.place.delegate('ul.gedit-tabarea li.gedit-tabadd', 'click', function(event){
var oldscene = editor.sceneArr[editor.sceneNum].getData();
var scenedata = {type: 'Scene', boundingBox: oldscene.boundingBox, showGrid: oldscene.showGrid};
editor.addScene(scenedata);
editor.setScene(editor.sceneArr.length - 1);
});
this.place.delegate('ul.gedit-tabarea li.gedit-tabcopy', 'click', function(event){
editor.addScene(editor.sceneArr[editor.sceneNum].getData());
editor.sceneNum = editor.sceneArr.length - 1;
editor.updateAll();
});
this.place.delegate('ul.gedit-tabarea li.gedit-tabremove', 'click', function(event){
if (editor.sceneArr.length > 0) {
var dialog = new GeoDialog(editor.place,
{
title: editor.localize('Remove picture'),
text: editor.localize('Remove are you sure'),
buttons: [
{
text: editor.localize('Cancel')
},
{
text: editor.localize('Ok'),
event: 'removescene',
data: {}
}
]
}
);
dialog.show();
}
});
}
/******
* Add handlers for Object list -events.
******/
GEditor.prototype.addHandlersObjlist = function(){
/*** Object list actions **********/
var editor = this;
this.place.delegate('ul.gedit-objectlist li.gedit-objectitem', 'click', function(event){
var listitem = $(this);
var geoid = listitem.attr('data-gedit-objectuniqueid');
editor.selectObject(geoid);
});
this.place.delegate('ul.gedit-objectlist li.gedit-objectitem .gedit-remove', 'click', function(event){
var listitem = $(this).parents('li').eq(0);
var objectId = listitem.attr('data-gedit-objectid');
editor.selectObject('scene');
editor.removeObject(objectId);
editor.updateAll();
return false;
})
this.place.delegate('ul.gedit-objectlist li.gedit-objectitem .gedit-visible', 'click', function(event){
var listitem = $(this).parents('li').eq(0);
var objectId = listitem.attr('data-gedit-objectid');
editor.toggleObjectVisibility(objectId);
editor.updateAll();
return false;
})
}
/******
* Add handlers for Property list -events.
******/
GEditor.prototype.addHandlersProplist = function(){
/*** Property area actions *********/
var editor = this;
this.place.delegate('div.gedit-propertyarea .gedit-advanced-toggle', 'click', function(event){
$(this).parents('.gedit-propertyarea').toggleClass('gedit-show-advanced');
});
this.place.delegate('div.gedit-propertyarea input[type="text"], div.gedit-propertyarea input[type="number"], textarea', 'blur', function(event){
editor.place.trigger('updatefromdialog');
});
this.place.delegate('div.gedit-propertyarea input[type="text"], div.gedit-propertyarea input[type="number"], textarea', 'keyup', function(event){
if (event.which === 13) {
editor.place.trigger('updatefromdialog');
}
});
this.place.delegate('div.gedit-propertyarea input, div.gedit-propertyarea select', 'change', function(event){
editor.place.trigger('updatefromdialog');
});
}
/******
* Add handlers for View -events.
******/
GEditor.prototype.addHandlersView = function(){
/*** View area actions **************************/
var editor = this;
this.place.delegate('div.gedit-scenearea[data-gedit-tooltype="Select"]', 'objectmoved', function(event, options){
editor.updateAll();
options.element.setData({x: options.x, y: options.y});
});
this.place.delegate('div.gedit-scenearea[data-gedit-tooltype="Select"]', 'objectselected', function(event, options){
var geoid = options.geoid;
if (editor.editable) {
if (options.delay) {
// Make sure, the click on GeoPoint etc. is the last one.
setTimeout(function(){editor.selectObject(geoid);}, 1);
} else {
editor.selectObject(geoid);
}
}
});
this.place.delegate('div.gedit-scenearea[data-gedit-tooltype="Select"]', 'objectupdate', function(event, options){
var ids = options.geoid;
if (editor.editable) {
editor.updateDepsFromBoard(ids);
editor.updateDialog();
}
editor.place.trigger('geoeditor_changed');
});
this.place.delegate('div.gedit-scenearea', 'clickonboard', function(event, options){
var objdata = editor.tool.click(options);
var geoid;
if (objdata && objdata.length > 0) {
for (var i = 0; i < objdata.length; i++){
geoid = editor.addNew(objdata[i]);
}
editor.updateAll();
editor.selectObject(geoid);
}
});
}
/******
* Add handlers for Tool -events.
******/
GEditor.prototype.addHandlersTool = function(){
/*** Tool area actions *********/
var editor = this;
this.place.delegate('ul.gedit-toolarea li.gedit-geotool, ul.gedit-subtoolarea li.gedit-geotool', 'click', function(event){
var button = $(this);
var toolType = button.attr('data-gedit-geotooltype');
editor.selectTool(toolType);
editor.updateView();
});
}
/******
* Add handlers for Navi -events.
******/
GEditor.prototype.addHandlersNavi = function(){
/*** Navi area actions *********/
var editor = this;
this.place.delegate('.gedit-naviarea .gedit-navi-up', 'click', function(event){
editor.moveScene('up');
});
this.place.delegate('.gedit-naviarea .gedit-navi-down', 'click', function(event){
editor.moveScene('down');
});
this.place.delegate('.gedit-naviarea .gedit-navi-left', 'click', function(event){
editor.moveScene('left');
});
this.place.delegate('.gedit-naviarea .gedit-navi-right', 'click', function(event){
editor.moveScene('right');
});
this.place.delegate('.gedit-naviarea .gedit-navi-zoomin', 'click', function(event){
editor.zoomScene('in');
});
this.place.delegate('.gedit-naviarea .gedit-navi-zoomout', 'click', function(event){
editor.zoomScene('out');
});
}
/******
* Add handlers for action -events.
******/
GEditor.prototype.addHandlersAction = function(){
/*** Tool area actions *********/
var editor = this;
this.place.bind('removescene', function(event, data){
editor.removeScene();
});
}
/******
* Select an object in current scene.
******/
GEditor.prototype.selectObject = function(geoid){
var objlist = this.layout.objectlist.find('li').removeClass('gedit-selected');
var selObj = this.layout.objectlist.find('li.gedit-objectitem[data-gedit-objectuniqueid="'+geoid+'"]');
if (selObj.length === 0) {
geoid = 'scene';
selObj = this.layout.objectlist.find('li.gedit-objectitem[data-gedit-objectuniqueid="'+geoid+'"]');
}
var objId = selObj.attr('data-gedit-objectid');
selObj.addClass('gedit-selected');
var dialog = this.sceneArr[this.sceneNum].getDialog(objId);
this.sceneArr[this.sceneNum].deselectObject(this.objectId);
this.objectId = geoid;
this.highlightObject(geoid);
this.setDialog(dialog);
}
/******
* Highlight an object in current scene.
******/
GEditor.prototype.highlightObject = function(geoid){
this.sceneArr[this.sceneNum].selectObject(geoid);
}
/******
* Select the tool.
******/
GEditor.prototype.selectTool = function(toolType){
var button = this.layout.toolarea.find('li[data-gedit-geotooltype="'+toolType+'"]')
.add(this.layout.subtoolarea.find('li[data-gedit-geotooltype="'+toolType+'"]')).eq(0);
button.closest('ul').find('li.gedit-geotool').removeClass('gedit-selected');
button.addClass('gedit-selected');
this.layout.scenearea.attr('data-gedit-tooltype', toolType);
this.tool = this.tools[toolType];
this.tool.init();
if (!this.tool.subtool) {
this.layout.subtoolarea.empty();
if (this.tool.subtools.length > 0) {
this.layout.subtoolarea.append('<li class="gedit-geotool gedit-selected" data-gedit-geotooltype="'+toolType+'" title="'+this.localize(toolType + '-tooltip')+'">'+this.tool.getIcon()+'<div class="gedit-toolshade"></div></li>');
}
for (var i = 0; i < this.tool.subtools.length; i++) {
var subtool = this.tool.subtools[i];
this.layout.subtoolarea.append('<li class="gedit-geotool" data-gedit-geotooltype="'+subtool+'" title="'+this.localize(subtool + '-tooltip')+'">'+this.tools[subtool].getIcon()+'<div class="gedit-toolshade"></div></li>');
}
}
this.updateInfo(this.tool.type + '-start');
}
/******
* Set the content of options dialog
******/
GEditor.prototype.setDialog = function(dialog){
var str = ['<div class="gedit-options-basic"><fieldset><legend>'+this.localize('Basic')+'</legend>',
'<table>\n<tbody>\n</tbody>\n</table>\n',
'</fieldset></div>',
'<div class="gedit-advanced-toggle">. . .</div>',
'<div class="gedit-options-advanced"><fieldset><legend>'+this.localize('Advanced')+'</legend>',
'<table>\n<tbody>\n</tbody>\n</table>\n',
'</fieldset></div>'
].join('\n');
this.layout.propertyarea.html(str); //.scrollTop(0);
var table = this.layout.propertyarea.find('.gedit-options-basic tbody');
for (var i = 0; i < dialog.basic.length; i++) {
table.append('<tr class="geoWidgetRow geoWidget-'+dialog.basic[i].type+'"><td><span class="geoItemCaption">'+this.localize(dialog.basic[i].label)+': </span></td><td><span class="geoProperty"></span></td></tr>');
var place = table.find('.geoProperty:last');
if (typeof(dialog.basic[i]) === 'object') {
var widgetConstr = this.widgets[dialog.basic[i].type];
var widget = new widgetConstr(place, dialog.basic[i]);
widget.init();
}
}
var table = this.layout.propertyarea.find('.gedit-options-advanced tbody');
for (var i = 0; i < dialog.advanced.length; i++) {
table.append('<tr class="geoWidgetRow geoWidget-'+dialog.advanced[i].type+'"><td><span class="geoItemCaption">'+this.localize(dialog.advanced[i].label)+': </span></td><td><span class="geoProperty"></span></td></tr>');
var place = table.find('.geoProperty:last');
if (typeof(dialog.advanced[i]) === 'object') {
var widgetConstr = this.widgets[dialog.advanced[i].type];
var widget = new widgetConstr(place, dialog.advanced[i]);
widget.init();
}
}
}
/******
* Refresh size
******/
GEditor.prototype.refreshSize = function(){
var scene = this.sceneArr[this.sceneNum];
var aspectRatio = scene.getAspectRatio();
var width = this.place.width() - this.layout.objectarea.width();
var height = width / aspectRatio;
var size = {width: width, height: height};
this.layout.scenearea.css(size);
//this.layout.scenearea.children('svg').css(size);
}
/******
* Update all parts
******/
GEditor.prototype.updateAll = function(){
var errors = this.updateView();
this.updateTabs();
if (this.editable) {
this.updateObjectlist(errors);
this.selectObject(this.objectId);
} else {
this.sceneArr[this.sceneNum].showCaption();
}
if (this.editable || this.sceneArr[this.sceneNum].allowControls) {
this.layout.naviarea.addClass('gedit-controls-on');
} else {
this.layout.naviarea.removeClass('gedit-controls-on');
}
}
/******
* Update the view.
******/
GEditor.prototype.updateView = function(){
this.clearAll();
this.layout.scenearea.empty();
this.refreshSize();
//var aspectRatio = this.sceneArr[this.sceneNum].getAspectRatio();
//var size = {width: this.layout.scenearea.width(), height: this.layout.scenearea.width() / aspectRatio};
//this.layout.scenearea.css(size);
var errors = this.sceneArr[this.sceneNum].draw('geditorbox-' + this.boxnum, !this.editable);
this.highlightObject(this.objectId);
this.place.trigger('geoeditor_changed');
return errors;
//this.layout.scenearea.find('svg').css(size).attr('viewbox', '0 0 800 800');
}
/******
* Update the property dialog.
******/
GEditor.prototype.updateDialog = function(){
var objIndex = this.layout.objectlist.find('li.gedit-objectitem[data-gedit-objectuniqueid="' + this.objectId + '"]').attr('data-gedit-objectid');
var dialog = this.sceneArr[this.sceneNum].getDialog(objIndex);
this.setDialog(dialog);
}
/******
* Update tabs
******/
GEditor.prototype.updateTabs = function(){
this.layout.tabarea.empty();
if (this.editable) {
this.layout.tabarea.append('<li class="gedit-tab gedit-tab-addremove gedit-tabremove">'+GEditor.strings.icons.removeminus+'</li>')
this.layout.tabarea.append('<li class="gedit-tab gedit-tab-addremove gedit-tabcopy">'+GEditor.strings.icons.copy+'</li>')
this.layout.tabarea.append('<li class="gedit-tab gedit-tab-addremove gedit-tabadd">'+GEditor.strings.icons.newplus+'</li>')
}
if (this.editable || (this.browsingMode === 'tabs' && this.sceneArr.length > 1)) {
for (var i = 0; i < this.sceneArr.length; i++){
var currClass = (this.sceneNum === i ? ' gedit-selected' : '');
this.layout.tabarea.append('<li class="gedit-tab'+currClass+'" data-gedit-scenenum="'+i+'">'+(this.sceneArr[i].name || (i+1))+'</li>');
}
} else if (!this.editable && this.browsingMode === 'tabless') {
this.layout.tabarea.addClass('gedit-tabarea-tabless');
this.layout.tabarea.append('<li class="gedit-tab gedit-tab-navi gedit-tabprev">'+GEditor.strings.icons.tablessprev+'</li>')
for (var i = 0; i < this.sceneArr.length; i++){
var currClass = (this.sceneNum === i ? ' gedit-selected' : '');
this.layout.tabarea.append('<li class="gedit-tab gedit-tabless'+currClass+'" data-gedit-scenenum="'+i+'">'+GEditor.strings.icons.tablessbutton+'</li>');
}
this.layout.tabarea.append('<li class="gedit-tab gedit-tab-navi gedit-tabnext">'+GEditor.strings.icons.tablessnext+'</li>')
}
}
/******
* Update objectlist
******/
GEditor.prototype.updateObjectlist = function(errors){
if (typeof(errors) === 'undefined') {
errors = [];
}
var selected = this.layout.objectlist.find('.gedit-selected').attr('data-gedit-objectid');
this.layout.objectlist.empty();
this.layout.objectlist.append('<li class="gedit-objectitem" data-gedit-objectid="scene" data-gedit-objectuniqueid="scene">'+ this.getSceneListItem()+'</li>');
var objlist = this.sceneArr[this.sceneNum].getObjectlist();
for (var i = 0; i < objlist.length; i++) {
var errorclass = (errors.indexOf(objlist[i].geoid) !== -1 ? ' gedit-error' : '');
this.layout.objectlist.append('<li class="gedit-objectitem' + errorclass + '" data-gedit-objectid="'+i+'" data-gedit-objectuniqueid="'+objlist[i].geoid+'" data-gedit-visible="'+(objlist[i].visible ? 'visible' : 'nonvisible')+'">'+ objlist[i].str+' <div class="gedit-objectitem-buttons"><div class="gedit-visible">'+GEditor.strings.icons.visible+'</div><div class="gedit-remove">'+GEditor.strings.icons.remove+'</div></div></li>');
}
this.layout.objectlist.find('li[data-gedit-objectid="'+selected+'"]').addClass('gedit-selected');
}
/******
* Update infoarea
******/
GEditor.prototype.updateInfo = function(message){
message = this.localize(message) || '<p> </p>';
this.layout.infoarea.html(message);
}
/******
* Update dependent data from the board.
******/
GEditor.prototype.updateDepsFromBoard = function(geoids){
//var deps = this.sceneArr[this.sceneNum].getDependents(geoids);
//deps = geoids.concat(deps);
// Don't bother to find dependencies. Update all instead.
deps = [];
this.sceneArr[this.sceneNum].updateFromBoard(deps);
}
/******
* Update data from dialog to the datastructure.
******/
GEditor.prototype.updateDataFromDialog = function(){
var data = {};
var inputs = this.layout.propertyarea.find('input[type="text"], input[type="color"], select, textarea');
for (var i = 0; i < inputs.length; i++){
var attr = inputs.eq(i).attr('data-geoattribute');
var value = inputs.eq(i).val();
data[attr] = value;
}
var inputs = this.layout.propertyarea.find('input[type="number"]');
for (var i = 0; i < inputs.length; i++){
var attr = inputs.eq(i).attr('data-geoattribute');
var value = inputs.eq(i).val();
data[attr] = value;
}
var inputs = this.layout.propertyarea.find('input[type="checkbox"]');
for (var i = 0; i < inputs.length; i++){
var attr = inputs.eq(i).attr('data-geoattribute');
data[attr] = inputs[i].checked;
}
this.setObjData(data);
var errors = this.updateView();
this.updateObjectlist(errors);
if (this.objectId === 'scene') {
this.updateTabs();
}
}
/******
* Add a new object
******/
GEditor.prototype.addNew = function(data){
data.geoid = data.geoid || this.getObjId(data.type);
return this.sceneArr[this.sceneNum].addObject(data);
}
/******
* Remove object
******/
GEditor.prototype.removeObject = function(objectId){
this.sceneArr[this.sceneNum].removeObject(objectId);
if (objectId == this.objectId) {
this.objectId = 'scene';
}
}
/******
* Toggle object visibility
******/
GEditor.prototype.toggleObjectVisibility = function(objectId){
this.sceneArr[this.sceneNum].toggleVisible(objectId);
if (objectId == this.objectId) {
this.objectId = 'scene';
}
}
/******
* Set the data of current object.
******/
GEditor.prototype.setObjData = function(data){
this.sceneArr[this.sceneNum].setObjData(this.objectId, data);
}
/******
* Get the data of given object.
******/
GEditor.prototype.getObjDataById = function(geoid){
return this.sceneArr[this.sceneNum].getObjData(geoid);
}
/******
* Get the data of current object.
******/
GEditor.prototype.getObjData = function(){
return this.sceneArr[this.sceneNum].getObjData(this.objectId);
}
/******
* Get list item for scene.
******/
GEditor.prototype.getSceneListItem = function(){
return this.sceneArr[this.sceneNum].getListStr();
}
/******
* Move scene view.
******/
GEditor.prototype.moveScene = function(direction){
this.sceneArr[this.sceneNum].move(direction);
this.updateAll();
}
/******
* Zoom scene view.
******/
GEditor.prototype.zoomScene = function(direction){
this.sceneArr[this.sceneNum].zoom(direction);
this.updateAll();
}
/******
* Get list of point-like objects.
******/
GEditor.prototype.getPointlikes = function(){
return this.sceneArr[this.sceneNum].getPointlikes();
}
/******
* Clear rendered images.
* Removing the renderer causes an error when freeBoard() is
* used. The renderer has no clear reference in the code.
* Contents of the freeBoard() function is copied below to
* fix the problem.
******/
GEditor.prototype.clearAll = function(){
// Go through the boards and find the right one.
for (var f in JXG.JSXGraph.boards) {
if (JXG.JSXGraph.boards[f].container === 'geditorbox-' + this.boxnum) {
if (typeof(f) === 'string') {
f = JXG.JSXGraph.boards[f];
}
f.removeEventHandlers();
for (var d = 0; d < f.containerObj.childNodes.length; d++) {
f.containerObj.removeChild(f.containerObj.childNodes[d]);
}
f.objects = new Object();
delete(f.algebra);
delete(JXG.JSXGraph.boards[f.id]);
}
}
}
/**
* Localize strings
*/
GEditor.prototype.localize = function(str, lang){
return this.localizer.localize(str, lang);
}
GEditor.templates = {
editorlayout: [
'<ul class="gedit-toolarea gedit-gradbg"></ul>',
'<ul class="gedit-subtoolarea gedit-gradbg-rev"></ul>',
'<div class="gedit-scenearea"></div>',
'<div class="gedit-naviarea"></div>',
'<div class="gedit-objectarea"><div class="gedit-propertyarea gedit-gradbg"></div><ul class="gedit-objectlist"></ul></div>',
'<ul class="gedit-tabarea gedit-gradbg"></ul>',
'<div class="gedit-infoarea gedit-gradbg"></div>'
].join('\n'),
viewlayout: [
'<div class="gedit-scenearea"></div>',
'<div class="gedit-naviarea"></div>',
'<ul class="gedit-tabarea gedit-gradbg"></ul>',
'<div class="gedit-infoarea gedit-gradbg"></div>'
].join('\n')
}
GEditor.strings = {
css: [
'.geoeditorwrapper {margin: 0.5em 0; box-sizing: border-box; -moz-box-sizing: border-box; width: 100%; border: 1px solid black; position: relative;}',
'.geoeditorwrapper.editmode {min-width: 600px;}',
'.geoeditorwrapper svg {display: inline-block;}',
'.gedit-gradbg {background: rgb(238,238,238);',
'background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1)));',
'background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 );}",
'.geoeditorwrapper .gedit-gradbg-rev {background: rgb(238,238,238);',
'background: -moz-linear-gradient(bottom, rgba(238,238,238,1) 0%, rgba(178,178,178,1) 100%);',
'background: -webkit-gradient(linear, left bottom, left top, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(178,178,178,1)));',
'background: -webkit-linear-gradient(bottom, rgba(238,238,238,1) 0%,rgba(178,178,178,1) 100%);',
'background: -o-linear-gradient(bottom, rgba(238,238,238,1) 0%,rgba(178,178,178,1) 100%);',
'background: -ms-linear-gradient(bottom, rgba(238,238,238,1) 0%,rgba(178,178,178,1) 100%);',
'background: linear-gradient(to top, rgba(238,238,238,1) 0%,rgba(178,178,178,1) 100%);',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b2b2b2', endColorstr='#eeeeee',GradientType=0 );}",
/*** Scenearea ***********/
'.geoeditorwrapper.editmode .gedit-scenearea {margin-right: 300px; min-width: 300px; min-height: 200px; background-color: white;}',
'.geoeditorwrapper.editmode .gedit-scenearea {cursor: crosshair;}',
'.geoeditorwrapper.editmode .gedit-scenearea[data-gedit-tooltype="Select"] {cursor: default;}',
'.geoeditorwrapper.viewmode .gedit-scenearea {margin-right: 0; min-height: 400px; background-color: white;}',
/*** Naviarea *************/
'.geoeditorwrapper .gedit-naviarea {position: absolute; right: 300px; margin-top: -70px; display: none; opacity: 0.2; transition: opacity 0.5s; -webkit-transition: opacity 0.5s;}',
'.geoeditorwrapper.viewmode .gedit-naviarea {right: 0;}',
'.geoeditorwrapper .gedit-naviarea:hover {opacity: 1;}',
'.geoeditorwrapper .gedit-naviarea.gedit-controls-on {display: block;}',
'.geoeditorwrapper .gedit-naviarea .gedit-navibutton:hover {cursor: pointer;}',
'.geoeditorwrapper .gedit-naviarea .gedit-navibutton:hover circle {fill: #faa;}',
/*** Objectarea ***********/
'.geoeditorwrapper.editmode .gedit-objectarea {position: absolute; top: 0; bottom: 0; right: 0; width: 300px; box-sizing: border-box; -moz-box-sizing: border-box; border-left: 1px solid black;}',
/*** Propertyarea ***********/
'.geoeditorwrapper.editmode .gedit-propertyarea {font-size: 80%; height: 250px; overflow-y: scroll; overflow-x: hidden; padding: 0.3em; box-sizing: border-box; -moz-box-sizing: border-box;}',
'.geoeditorwrapper.editmode .gedit-propertyarea fieldset table {width: 100%;}',
'.geoeditorwrapper.editmode .gedit-propertyarea fieldset table td {vertical-align: top;}',
'.geoeditorwrapper.editmode .gedit-propertyarea input[type="text"], .geoeditorwrapper.editmode .gedit-propertyarea input[type="color"], .geoeditorwrapper.editmode .gedit-propertyarea input[type="number"] {display: block; width: 100%;}',
'.geoeditorwrapper.editmode .gedit-propertyarea textarea {box-sizing: content-box; -moz-box-sizing: content-box; width: 100%; height: 4em; padding: 0; margin: 0;}',
'.geoeditorwrapper.editmode .gedit-propertyarea .gedit-options-advanced {overflow: hidden; height: 0; -moz-transition: all 0.2s ease-out; -webkit-transition: all 0.2s ease-out; -ie-transition: all 0.2s ease-out; transition: all 0.2s ease-out;}',
'.geoeditorwrapper.editmode .gedit-propertyarea .gedit-advanced-toggle {display: block; text-align: center; font-size: 50%; line-height: 0.8em; padding-bottom: 0.5em; cursor: pointer; font-weight: bold; text-shadow: -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.7);}',
'.geoeditorwrapper.editmode .gedit-propertyarea .gedit-advanced-toggle:hover {background-color: rgba(255,255,255,0.8);}',
'.geoeditorwrapper.editmode .gedit-propertyarea.gedit-show-advanced .gedit-options-advanced {height: auto; -moz-transition: all 0.4s ease-out; -webkit-transition: all 0.4s ease-out; -ie-transition: all 0.4s ease-out; transition: all 0.4s ease-out;}',
'.geoeditorwrapper .gedit-propertyarea tr.geoWidget-Label {font-size: 70%; color: #777;}',
/*** Object list ***********/
'.geoeditorwrapper.editmode ul.gedit-objectlist {position: absolute; top: 250px; left: 0; right: 0; bottom: 0; overflow-x: hidden; overflow-y: scroll; list-style: none; margin: 0; padding: 0; background-color: white; border-top: 1px solid black;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li {padding: 0.1em 0.2em; border-bottom: 1px solid #999; cursor: pointer;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li.gedit-selected {background-color: #ffa; box-shadow: inset 0 2px 5px rgba(255,255,255,0.8), inset 0 -2px 5px rgba(0,0,0,0.3);}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li.gedit-error {background-color: #fdd;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li.gedit-selected.gedit-error {background-color: #fda;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li > div {display: inline-block; vertical-align: middle;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li div.gedit-objectitem-buttons {display: inline-block; vertical-align: middle; float: right;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li div.gedit-objectitem-buttons > div {display: inline-block; cursor: pointer;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li div.gedit-objectitem-buttons .gedit-visible {margin-right: 0.7em;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li .gedit-listicon {margin-right: 15px;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li .gedit-listname {font-family: serif;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li .gedit-listname sub {font-size: 60%;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li .gedit-listname .geoedit-aka {color: #555; font-size: 80%;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li div.gedit-objectitem-buttons .gedit-visible svg .nonvisible {display: none}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li[data-gedit-visible="nonvisible"] div.gedit-objectitem-buttons .gedit-visible svg .nonvisible {display: inherit;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li[data-gedit-visible="nonvisible"] div.gedit-objectitem-buttons .gedit-visible svg .visible {stroke: #999;}',
'.geoeditorwrapper.editmode ul.gedit-objectlist li[data-gedit-visible="nonvisible"] {background-color: rgba(170,170,170,0.2);}',
/*** Tabarea ***********/
'.geoeditorwrapper.editmode .gedit-tabarea {border-top: 1px solid black; margin-right: 300px; list-style: none; padding: 0 0.5em 0.2em; margin: 0;}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab {margin: 0; margin-top: -1px; padding: 0.2em 0.4em; border: 1px solid black; border-top: 1px solid white; border-radius: 0 0 0.2em 0.2em; background-color: #f6f6f6; display: inline-block; min-width: 1em; text-align: center; cursor: pointer;}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab.gedit-selected {padding-bottom: 0.5em; background-color: white; font-weight: bold;}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab:hover, .geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab.gedit-selected:hover {background-color: rgba(255,200,200,0.8); border-color: #a00; border-top-color: rgba(255,200,200,0.8); }',
'.geoeditorwrapper.viewmode .gedit-tabarea {border-top: 1px solid black; margin-right: 40%; list-style: none; padding: 0 0.5em 0.2em; margin: 0;}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab-addremove {border: 1px solid black; border-radius: 50%; height: 18px; width: 18px; vertical-align: middle; line-height: 22px; padding: 2px; margin-left: 0.2em; margin-top: 0.3em; box-shadow: 0px 3px 2px rgba(0,0,0,0.2), 3px 0px 2px rgba(0,0,0,0.2), -2px -2px 2px rgba(255,255,255,0.5), inset 1px 1px 2px rgba(0,0,0,0.2), inset -1px -1px 2px rgba(255,255,255,0.2);}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab-addremove:hover {border: 1px solid #a00; background-color: rgba(255,200,200,0.8);}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab.gedit-tab-addremove.gedit-tabremove { margin-left: 0.5em;}',
'.geoeditorwrapper.editmode .gedit-tabarea li.gedit-tab.gedit-tab-addremove.gedit-tabadd { margin-right: 2em;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab {margin: 0; margin-top: -1px; padding: 0.2em 0.4em; border: 1px solid black; border-top: none; border-radius: 0 0 0.4em 0.4em; background-color: white; display: inline-block; min-width: 1em; text-align: center; cursor: pointer;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-selected {padding-bottom: 0.5em; font-weight: bold;}',
/*** Tabarea tabless ****/
'.geoeditorwrapper.viewmode .gedit-tabarea.gedit-tabarea-tabless {text-align: center; padding: 0; padding-top: 0.2em;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tabless, .geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tab-navi {border-radius: 0; border: none; background: transparent; vertical-align: middle; margin: 0; padding:0;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tabless.gedit-selected {padding: 0;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tabless.gedit-selected svg .selectable {fill: #555;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tabless.gedit-selected svg .highlight {stroke: blue; stroke-width: 2px;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tabless:hover svg .highlight {stroke: #a00; fill: rgba(255,0,0,0.3); stroke-width: 2px;}',
'.geoeditorwrapper.viewmode .gedit-tabarea li.gedit-tab.gedit-tab-navi:hover svg .highlight {stroke: #a00; fill: rgba(255,0,0,0.3); stroke-width: 2px;}',
/*** Toolarea ***********/
'.geoeditorwrapper.editmode .gedit-toolarea {list-style: none; margin: 0; padding: 0 4px; border-top: 1px solid #888; border-bottom: 1px solid #888; margin-right: 300px;}',
'.geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool {margin: 2px 0; display: inline-block; line-height: 24px; width: 24px; height: 24px; padding: 2px; text-align: center; vertical-align: middle; border: 1px solid #888; border-radius: 4px; box-shadow: -1px -1px 1px rgba(0,0,0,0.3), inset 1px 1px 1px rgba(255,255,255,0.6), inset -1px -1px 1px rgba(0,0,0,0.3), 1px 1px 1px rgba(255,255,255,0.6); cursor: pointer; position: relative;}',
'.geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool:hover {background-color: rgba(255,255,255,0.6);}',
'.geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool:active, .geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool.gedit-selected {padding: 3px 1px 1px 3px; box-shadow: -1px -1px 1px rgba(0,0,0,0.4), inset 1px 1px 1px rgba(0,0,0,0.4), inset -1px -1px 1px rgba(255,255,255,0.5), 1px 1px 1px rgba(255,255,255,0.5); background-color: rgba(255,255,255,0.6);}',
'.geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool .gedit-toolshade {position: absolute; top: 0; bottom: 0; left: 0; right: 0;}',
'.geoeditorwrapper.editmode .gedit-toolarea li.gedit-geotool svg {width: 22px; height: 22px;}',
/*** SubToolarea ***********/
'.geoeditorwrapper.editmode .gedit-subtoolarea {list-style: none; margin: 0; padding: 0 10px; border-bottom: 1px solid #888; margin-right: 300px; min-height: 30px; background-color: #eee;}',
'.geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool {margin: 2px 3px; display: inline-block; line-height: 22px; width: 19px; height: 19px; padding: 2px; text-align: center; vertical-align: middle; border: 1px solid #666; border-radius: 4px; cursor: pointer; position: relative; background-color: #ddd;}',
'.geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool:hover {background-color: rgba(255,255,255,0.6);}',
'.geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool:active, .geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool.gedit-selected {padding: 3px 1px 1px 3px; border: 1px solid black; background-color: rgba(255,255,100,0.8); background-color: white;}',
'.geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool .gedit-toolshade {position: absolute; top: 0; bottom: 0; left: 0; right: 0;}',
'.geoeditorwrapper.editmode .gedit-subtoolarea li.gedit-geotool svg {width: 15px; height: 15px;}',
/*** Infoarea ***********/
'.geoeditorwrapper .gedit-infoarea {min-height: 1.5em; margin-right: 300px; border-top: 1px solid #ddd; border-bottom: 1px solid #999;}',
'.geoeditorwrapper.viewmode .gedit-infoarea {margin-right: 0;}',
'.geoeditorwrapper .gedit-infoarea p {margin: 0 0.3em; padding: 0.2em 0.5em; font-size: 80%; background-color: rgba(255,255,255,0.7); border-top: none; border-left: 1px solid #444; border-right: 1px solid #ddd; border-bottom: none; min-height: 1em;}',
'.geoeditorwrapper .gedit-infoarea p:first-child {margin-top: 0.2em; border-top: 1px solid #444;}',
'.geoeditorwrapper .gedit-infoarea p:last-child {margin-bottom: 0.2em; border-bottom: 1px solid #ddd;}'
].join('\n'),
icons: {
remove: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-remove"><path style="stroke: none;" d="M7 4 l6 0 l0 -2 l4 0 l0 2 l6 0 l0 2 l-16 0z M7 8 l16 0 l0 19 l-1 1 l-14 0 l-1 -1z M9 10 l0 15 l3 0 l0 -15z M13.7 10 l0 15 l3 0 l0 -15z M21.1 10 l-3 0 l0 15 l3 0z" /></svg>',
copy: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15" viewbox="0 0 30 30" class="mini-icon mini-icon-copy"><path style="stroke: none;" d="M2 2 l18 0 l0 6 l-12 0 l0 17 l-6 0 z M10 10 l8 0 l0 10 l10 0 l0 10 l-18 0 z M20 10 l8 8 l-8 0 z" /></svg>',
newplus: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15" viewbox="0 0 30 30" class="mini-icon mini-icon-newplus"><path style="stroke: none;" d="M13 7 l4 0 l0 6 l6 0 l0 4 l-6 0 l0 6 l-4 0 l0 -6 l-6 0 l0 -4 l6 0z" /></svg>',
removeminus: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="15" height="15" viewbox="0 0 30 30" class="mini-icon mini-icon-removeminus"><path style="stroke: none;" d="M7 13 l16 0 l0 4 l-16 0 z" /></svg>',
tablessbutton: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-tablessbutton"><circle class="highlight" fill="none" stroke="none" cx="15.5" cy="15.5" r="10" /><circle class="selectable" fill="#999" stroke="none" cx="15.5" cy="15.5" r="7" /></svg>',
tablessprev: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-previous"><path class="highlight" fill="#999" stroke="none" d="M20 3 l-12 12.5 l12 12.5 l-5 -13.5 z" /></svg>',
tablessnext: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-next"><path class="highlight" fill="#999" stroke="none" d="M10 3 l12 12.5 l-12 12.5 l5 -13.5 z" /></svg>',
visible: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-visible"><path class="visible" fill="white" stroke="black" d="M2 15.5 a15 15 0 0 0 26 0 a15 15 0 0 0 -26 0z" /><circle class="visible" fill="white" stroke="black" cx="15.5" cy="15.5" r="6" /><circle class="visible" fill="black" stroke="none" cx="15.5" cy="15.5" r="3" /><path class="visible" fill="none" stroke="black" stroke-width="2" d="M2 15.5 a15 15 0 0 1 26 0" /><line class="nonvisible" stroke="#a00" stroke-width="3" x1="28" y1="2" x2="2" y2="28" /></svg>'
},
tools: {
navigation: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="105" height="70" viewbox="0 0 150 100" class="geoedit-tool geoedit-navitool"><g transform="translate(50 25)" class="gedit-navibutton gedit-navi-up"><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="14" /><path style="stroke: none; fill: #333;" d="M2 -2 l0 8 a2 2 0 0 1 -4 0 l0 -8 l-3 3 a2 2 0 0 1 -3 -3 l6 -6 a3 3 0 0 1 4 0 l6 6 a2 2 0 0 1 -3 3z" /></g><g transform="translate(50 75) rotate(180)" class="gedit-navibutton gedit-navi-down"><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="14" /><path style="stroke: none; fill: #333;" d="M2 -2 l0 8 a2 2 0 0 1 -4 0 l0 -8 l-3 3 a2 2 0 0 1 -3 -3 l6 -6 a3 3 0 0 1 4 0 l6 6 a2 2 0 0 1 -3 3z" /></g><g transform="translate(25 50) rotate(-90)" class="gedit-navibutton gedit-navi-left"><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="14" /><path style="stroke: none; fill: #333;" d="M2 -2 l0 8 a2 2 0 0 1 -4 0 l0 -8 l-3 3 a2 2 0 0 1 -3 -3 l6 -6 a3 3 0 0 1 4 0 l6 6 a2 2 0 0 1 -3 3z" /></g><g transform="translate(75 50) rotate(90)" class="gedit-navibutton gedit-navi-right"><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="14" /><path style="stroke: none; fill: #333;" d="M2 -2 l0 8 a2 2 0 0 1 -4 0 l0 -8 l-3 3 a2 2 0 0 1 -3 -3 l6 -6 a3 3 0 0 1 4 0 l6 6 a2 2 0 0 1 -3 3z" /></g><g transform="translate(125 20)" class="gedit-navibutton gedit-navi-zoomin"><rect x="-22" y="-12" width="34" height="34" fill="transparent" /><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="10" /><path style="stroke: none; fill: #333;" d="M-11 7 l-10 10 a2 2 0 0 0 4 4 l10 -10z" /><path style="stroke: none; fill: #333;" d="M-1.5 -1.5 l0 -5 l3 0 l0 5 l5 0 l0 3 l-5 0 l0 5 l-3 0 l0 -5 l-5 0 l0 -3z" /></g><g transform="translate(125 70)" class="gedit-navibutton gedit-navi-zoomout"><rect x="-22" y="-12" width="34" height="34" fill="transparent" /><circle style="stroke: #333; stroke-width: 4;" fill="#eee" cx="0" cy="0" r="10" /><path style="stroke: none; fill: #333;" d="M-11 7 l-10 10 a2 2 0 0 0 4 4 l10 -10z" /><path style="stroke: none; fill: #333;" d="M-6.5 -1.5 l13 0 l0 3 l-13 0z" /></g></svg>'
}
}
}
{ /*** Localizer **************************************************************/
var Localizer = function(lang){
this.lang = lang || 'en';
}
/**
* Localize strings
*/
Localizer.prototype.localize = function(str, lang){
lang = lang || this.lang;
return (this.dict && this.dict[str] && (this.dict[str][lang] || this.dict[str]['en'])) || str;
}
/**
* Add new terms to dictionary as an object.
*/
Localizer.addTerms = function(terms){
for (var item in terms){
if (typeof(Localizer.prototype.dict[item]) === 'undefined') {
Localizer.prototype.dict[item] = terms[item];
}
}
}
/**
* Which languages use decimal period.
*/
Localizer.prototype.decimalPeriod = {
'en': false,
'fi': true,
'sv': true,
'et': true
}
/**
* Return the usage of decimal period in this.language.
*/
Localizer.prototype.decimalperiod = function(){
return this.decimalPeriod[this.lang];
}
/** GeoEditor **********/
Localizer.prototype.dict = {
'Basic': {
'en': 'Basic',
'fi': 'Perusominaisuudet',
'sv': 'Grundfunktioner'
},
'Advanced': {
'en': 'Advanced',
'fi': 'Lisäominaisuudet',
'sv': 'Tilläggsfunktioner'
},
'Remove are you sure': {
'en': '<p>You are removing picture on this tab.</p><p>Are you sure?</p>',
'fi': '<p>Olet poistamassa tämän välilehden kuvaa.</p><p>Oletko varma?</p>',
'sv': '<p>Du håller på att radera bilden på denna tab.</p><p>Är du säker?</p>'
},
'Remove picture': {
'en': 'Remove picture',
'fi': 'Poista kuva',
'sv': 'Ta bort bild'
},
'Ok': {
'en': 'Ok',
'fi': 'Ok',
'sv': 'Ok'
},
'Cancel': {
'en': 'Cancel',
'fi': 'Peruuta',
'sv': 'Ã…ngra'
}
}
/** GeoScene *************/
Localizer.addTerms({
'Name': {
'en': 'Name',
'fi': 'Nimi',
'sv': 'Namn'
},
'Description': {
'en': 'Description',
'fi': 'Kuvateksti',
'sv': 'Bildtext'
},
'Show grid': {
'en': 'Show grid',
'fi': 'Näytä ruudukko',
'sv': 'Visa rutfält'
},
'Show axis': {
'en': 'Show axis',
'fi': 'Näytä akselit',
'sv': 'Visa axlarna'
},
'Static': {
'en': 'Static',
'fi': 'Kiinnitetty',
'sv': 'Statisk'
},
'Allow controls': {
'en': 'Allow controls',
'fi': 'Salli hallinta',
'sv': 'Tillåt redigering'
},
'Bounding box': {
'en': 'Bounding box',
'fi': 'Kuvan rajat',
'sv': 'Bildens gränser'
}
});
/** GeoObject ************/
Localizer.addTerms({
'Label': {
'en': 'Label',
'fi': 'Nimi',
'sv': 'Namn'
},
'Color': {
'en': 'Color',
'fi': 'Väri',
'sv': 'Färg'
},
'Stroke color': {
'en': 'Stroke color',
'fi': 'Viivan väri',
'sv': 'Linjens färg'
},
'Fill color': {
'en': 'Fill color',
'fi': 'Täytön väri',
'sv': 'Fyllnadsfärg'
},
'Stroke width': {
'en': 'Stroke width',
'fi': 'Viivan paksuus',
'sv': 'Linjens bredd'
},
'Visible': {
'en': 'Visible',
'fi': 'Näkyvissä',
'sv': 'Synlig'
},
'Show label': {
'en': 'Show label',
'fi': 'Näytä nimi',
'sv': 'Visa namn'
},
'Fixed': {
'en': 'Fixed',
'fi': 'Kiinteä',
'sv': 'Fast'
},
'Size': {
'en': 'Size',
'fi': 'Koko',
'sv': 'Storlek'
},
'Line style': {
'en': 'Line style',
'fi': 'Viivan tyyli',
'sv': 'Linjens typ'
}
});
/** GeoPoint *************/
Localizer.addTerms({
'x-coordinate': {
'en': 'x-coordinate',
'fi': 'x-koordinaatti',
'sv': 'x-koordinat'
},
'y-coordinate': {
'en': 'y-coordinate',
'fi': 'y-koordinaatti',
'sv': 'y-koordinat'
},
'Snap to grid': {
'en': 'Snap to grid',
'fi': 'Napsahda ruudukkoon',
'sv': 'Fäst vid rutfältet'
}
});
/** GeoLine ***********/
Localizer.addTerms({
'First point': {
'en': 'First point',
'fi': 'Ensimmäinen piste',
'sv': 'Första punkten'
},
'Second point': {
'en': 'Second point',
'fi': 'Toinen piste',
'sv': 'Andra punkten'
},
'Line type': {
'en': 'Line type',
'fi': 'Suoran tyyppi',
'sv': 'Typ av linje'
},
'Arrow at start': {
'en': 'Arrow at start',
'fi': 'Nuoli alussa',
'sv': 'Pil i början'
},
'Arrow at end': {
'en': 'Arrow at end',
'fi': 'Nuoli lopussa',
'sv': 'Pil i slutet'
},
'Line': {
'en': 'Line',
'fi': 'Suora',
'sv': 'Linje'
},
'Line segment': {
'en': 'Line segment',
'fi': 'Jana',
'sv': 'Sträcka'
},
'Starting line segment': {
'en': 'Starting line segment',
'fi': 'Puolisuora pisteestä',
'sv': 'Stråle från en punkt'
},
'Ending line segment': {
'en': 'Ending line segment',
'fi': 'Puolisuora pisteeseen',
'sv': 'Stråle till en punkt'
}
});
/** GeoCircle ************/
Localizer.addTerms({
'Center point': {
'en': 'Center point',
'fi': 'Keskipiste',
'sv': 'Medelpunkt'
},
'Arc point': {
'en': 'Arc point',
'fi': 'Kehäpiste',
'sv': 'Periferipunkt'
}
});
/** GeoRcircle *************/
Localizer.addTerms({
'Center point': {
'en': 'Center point',
'fi': 'Keskipiste',
'sv': 'Medelpunkt'
},
'Radius start': {
'en': 'Start point of radius',
'fi': 'Säteen alkupiste',
'sv': 'Radiens startpunkt'
},
'Radius end': {
'en': 'End point of radius',
'fi': 'Säteen päätepiste',
'sv': 'Radiens ändpunkt'
}
});
/** GeoGlider *********/
Localizer.addTerms({
'x-coordinate': {
'en': 'x-coordinate',
'fi': 'x-koordinaatti',
'sv': 'x-koordinat'
},
'y-coordinate': {
'en': 'y-coordinate',
'fi': 'y-koordinaatti',
'sv': 'y-koordinat'
},
'Parent': {
'en': 'On the element',
'fi': 'Käyrällä',
'sv': 'PÃ¥ elementet'
}
});
/** GeoMidpoint ***************/
Localizer.addTerms({
'Point 1': {
'en': 'Point 1',
'fi': '1. piste',
'sv': 'Punkt 1'
},
'Point 2': {
'en': 'Point 2',
'fi': '2. piste',
'sv': 'Punkt 2'
}
});
/** GeoIntersection **********/
Localizer.addTerms({
'Parent 1': {
'en': 'First curve',
'fi': 'Käyrä 1',
'sv': 'Element 1'
},
'Parent': {
'en': 'Second curve',
'fi': 'Käyrä 2',
'sv': 'Element 2'
},
'Show points': {
'en': 'Show points',
'fi': 'Näytä pisteet',
'sv': 'Visa punkter'
},
'both': {
'en': 'Both',
'fi': 'Molemmat',
'sv': 'BÃ¥da'
},
'first': {
'en': 'First',
'fi': 'Ensimmäinen',
'sv': 'Den första'
},
'second': {
'en': 'Second',
'fi': 'Toinen',
'sv': 'Den andra'
}
});
/** GeoTriangle *********/
Localizer.addTerms({
'First point': {
'en': 'First point',
'fi': 'Ensimmäinen piste',
'sv': 'Den första punkten'
},
'Second point': {
'en': 'Second point',
'fi': 'Toinen piste',
'sv': 'Den andra punkten'
},
'Third point': {
'en': 'Third point',
'fi': 'Kolmas piste',
'sv': 'Den tredje punkten'
}
});
/** GeoRighttriangle / GeoRtriangle ********/
Localizer.addTerms({
'First point': {
'en': 'First point',
'fi': 'Ensimmäinen piste',
'sv': 'Den första punkten'
},
'Second point': {
'en': 'Second point',
'fi': 'Toinen piste',
'sv': 'Den andra punkten'
},
'Third point name': {
'en': 'Third point name',
'fi': 'Kolmannen pisteen nimi',
'sv': 'Den tredje punktens namn'
},
'Show generated point': {
'en': 'Show third point',
'fi': 'Näytä kolmas piste',
'sv': 'Visa den tredje punkten'
},
'Show generated name': {
'en': 'Show the name of third point',
'fi': 'Näytä kolmannen pisteen nimi',
'sv': 'Visa den tredje punktens namn'
},
'Show right angle': {
'en': 'Show mark for right angle',
'fi': 'Näytä suoran kulman merkki'
}
});
/** GeoAngle **********/
Localizer.addTerms({
'Right point': {
'en': 'Right point',
'fi': 'Oikean kyljen piste',
'sv': 'Högra sidans punkt'
},
'Corner point': {
'en': 'Corner point',
'fi': 'Kärkipiste',
'sv': 'Spetspunkt'
},
'Left point': {
'en': 'Left point',
'fi': 'Vasemman kyljen piste',
'sv': 'Högra sidans punkt'
},
'Angle mode': {
'en': 'Angle mode',
'fi': 'Kulman tyyppi',
'sv': 'Typ av vinkel'
},
'Angle': {
'en': 'Angle',
'fi': 'Kulma',
'sv': 'Vinkel'
},
'Small angle': {
'en': 'Small angle',
'fi': 'Pienempi kulma',
'sv': 'Mindre vinkel'
},
'Large angle': {
'en': 'Large angle',
'fi': 'Suurempi kulma',
'sv': 'Större vinkel'
},
'Radius': {
'en': 'Radius',
'fi': 'Säde',
'sv': 'Radie'
},
'Fill opacity': {
'en': 'Fill opacity',
'fi': 'Täytön peittävyys',
'sv': 'Fyllnads opacitet'
}
});
/** GeoBisector **********/
Localizer.addTerms({
'Right point': {
'en': 'Right point',
'fi': 'Oikean kyljen piste',
'sv': 'Högra sidans punkt'
},
'Corner point': {
'en': 'Corner point',
'fi': 'Kärkipiste',
'sv': 'Spetspunkt'
},
'Left point': {
'en': 'Left point',
'fi': 'Vasemman kyljen piste',
'sv': 'Högra sidans punkt'
},
'Is ray': {
'en': 'Ray',
'fi': 'Puolisuora',
'sv': 'En stråle'
},
'Bisector': {
'en': 'Bisector',
'fi': 'Kulmanpuolittaja',
'sv': 'Bisektris'
}
});
/** GeoNormal *********/
Localizer.addTerms({
'Point': {
'en': 'Point',
'fi': 'Piste',
'sv': 'Punkt'
},
'Curve': {
'en': 'Curve',
'fi': 'Käyrä',
'sv': 'Kurva'
},
'Line type': {
'en': 'Line type',
'fi': 'Suoran tyyppi',
'sv': 'Typ av linje'
},
'Line': {
'en': 'Line',
'fi': 'Suora',
'sv': 'Linje'
},
'Line segment': {
'en': 'Line segment',
'fi': 'Jana',
'sv': 'Spetspunkt'
},
'Starting line segment': {
'en': 'Starting line segment',
'fi': 'Puolisuora pisteestä',
'sv': 'En stråle från en punkt'
},
'Ending line segment': {
'en': 'Ending line segment',
'fi': 'Puolisuora pisteeseen',
'sv': 'En stråle till en punkt'
}
});
/** GeoParallel ********/
/** GeoTangent ************/
Localizer.addTerms({
'Intersection 1 name': {
'en': 'Name of 1st intersection',
'fi': '1. leikkauspisteen nimi'
},
'Intersection 2 name': {
'en': 'Name of 2nd intersection',
'fi': '2. leikkauspisteen nimi'
}
});
/** GeoRectangle ********/
Localizer.addTerms({
'First point': {
'en': 'First point',
'fi': 'Ensimmäinen piste',
'sv': 'Första punkten'
},
'Second point': {
'en': 'Second point',
'fi': 'Toinen piste',
'sv': 'Andra punkten'
},
'Third point name': {
'en': 'Third point\'s name',
'fi': 'Kolmannen pisteen nimi',
'sv': 'Tredje punktens namn'
},
'Fourth point name': {
'en': 'Fourth point\'s name',
'fi': 'Neljännen pisteen nimi',
'sv': 'Fjärde punktens namn'
},
'Show third point': {
'en': 'Show the third point',
'fi': 'Näytä kolmas piste',
'sv': 'Visa tredje punkten'
},
'Show fourth point': {
'en': 'Show the fourth point',
'fi': 'Näytä neljäs piste',
'sv': 'Visa fjärde punkten'
},
'Show third point name': {
'en': 'Show the name of the third point',
'fi': 'Näytä kolmannen pisteen nimi',
'sv': 'Visa tredje punktens namn'
},
'Show fourth point name': {
'en': 'Show the name of the fourth point',
'fi': 'Näytä neljännen pisteen nimi',
'sv': 'Visa fjärde punktens namn'
}
});
/** GeoParallelogram *******/
/** GeoLabel **********/
Localizer.addTerms({
'Caption': {
'en': 'Caption',
'fi': 'Teksti',
'sv': 'Text'
},
'Text size': {
'en': 'Text size',
'fi': 'Tekstin koko',
'sv': 'Textstorlek'
}
});
/***************
* Geotools
****************/
/** GeoToolSelect ******/
Localizer.addTerms({
'Select-start': {
'en': '<p>Click object to select or drag to move it.</p>',
'fi': '<p>Valitse kuvio klikkaamalla tai siirrä raahaamalla.</p>',
'sv': '<p>Välj object genom att klicka eller flytta genom att dra.</p>'
},
'Select-tooltip': {
'en': 'Select / Move',
'fi': 'Valinta / Siirto',
'sv': 'Val / Förflyttning'
}
});
/** GeoToolPoint *****/
Localizer.addTerms({
'Point-start': {
'en': '<p>Click on the drawing area to add a point.</p>',
'fi': '<p>Lisää piste klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Lägg till en punkt genom att klicka på ritområdet.</p>'
},
'Point-maintooltip': {
'en': 'Point',
'fi': 'Piste',
'sv': 'Punkt'
},
'Point-tooltip': {
'en': 'Point',
'fi': 'Piste',
'sv': 'Punkt'
}
});
/** GeoToolLine *********/
Localizer.addTerms({
'Line-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first</strong> point of line.</p>',
'fi': '<p>Valitse tai lisää suoran <strong>ensimmäinen</strong> piste klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Välj eller lägg till linjens <strong>första</strong> punkt genom att klicka på ritområdet.</p>'
},
'Line-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>second</strong> point of line.</p>',
'fi': '<p>Valitse tai lisää suoran <strong>toinen</strong> piste klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Välj eller lägg till linjens <strong>andra</strong> punkt genom att klicka på ritområdet.</p>'
},
'Line-maintooltip': {
'en': 'Line / Segment',
'fi': 'Suora / Jana',
'sv': 'Linje / Sträcka'
},
'Line-tooltip': {
'en': 'Line / Segment',
'fi': 'Suora / Jana',
'sv': 'Linje / Sträcka'
}
});
/** GeoToolCircle ******/
Localizer.addTerms({
'Circle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>center point</strong> of the circle.</p>',
'fi': '<p>Valitse tai lisää ympyrän <strong>keskipiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Välj eller lägg cirkelns <strong>medelpunkt</strong> genom att klicka på ritområdet.</p>'
},
'Circle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>arc point</strong> of the circle.</p>',
'fi': '<p>Valitse tai lisää ympyrän <strong>kehäpiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Välj eller lägg cirkelns <strong>periferipunkt</strong> genom att klicka på ritområdet.</p>'
},
'Circle-maintooltip': {
'en': 'Circle',
'fi': 'Ympyrä',
'sv': 'Cirkel'
},
'Circle-tooltip': {
'en': 'Circle with center and arc point',
'fi': 'Ympyrä keski- ja kehäpisteillä',
'sv': 'En cirkel med en medel- samt periferipunkt'
}
});
/** GeoToolRcircle ******/
Localizer.addTerms({
'Rcircle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>center point</strong> of the circle.</p>',
'fi': '<p>Valitse tai lisää ympyrän <strong>keskipiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Välj eller lägg cirkelns <strong>medelpunkt</strong> genom att klicka på ritområdet.</p>'
},
'Rcircle-1': {
'en': '<p>Click on a <strong>segment</strong> to select radius or a <strong>point</strong> to select starting point of radius.</p>',
'fi': '<p>Valitse <strong>jana</strong> säteeksi tai <strong>piste</strong> säteen alkupisteeksi.</p>',
'sv': '<p>Klicka på en <strong>sträcka</strong> för att välja radie eller på en <strong>punkt</strong> för att välja startpunkt för radien.</p>'
},
'Rcircle-2': {
'en': '<p>Click on a <strong>point</strong> to select ending point of radius.</p>',
'fi': '<p>Valitse <strong>piste</strong> säteen päätepisteeksi.</p>',
'sv': '<p>Klicka på en <strong>punkt</strong> för att välja ändpunkten för radien.</p>'
},
'Rcircle-error': {
'en': '<p>You missed point or segment. Click again.</p>',
'fi': '<p>Et osunut pisteeseen tai janaan. Klikkaa uudelleen.</p>',
'sv': '<p>Du missade punkten eller sträckan. Klicka igen.</p>',
},
'Rcircle-error-1': {
'en': '<p>You missed point or segment. Click on a <strong>segment</strong> to select radius or a <strong>point</strong> to select starting point of radius.</p>',
'fi': '<p>Et osunut pisteeseen tai janaan. Valitse <strong>jana</strong> säteeksi tai <strong>piste</strong> säteen alkupisteeksi.</p>',
'sv': '<p>Du missade punkten eller sträckan. Klicka på en <strong>sträcka</strong> för att välja radie eller på en <strong>punkt</strong> för att välja startpunkt för radien.</p>'
},
'Rcircle-error-2': {
'en': '<p>You missed point. Click on a <strong>point</strong> to select ending point of radius.</p>',
'fi': '<p>Et osunut pisteeseen. Valitse <strong>piste</strong> säteen päätepisteeksi.</p>',
'sv': '<p>Du missade punkten. Klicka på en <strong>punkt</strong> för att välja ändpunkt för radien.</p>'
},
'Rcircle-tooltip': {
'en': 'Circle with center and radius from segment / two points',
'fi': 'Ympyrä keskipisteellä ja kahdesta pisteestä / janasta saadulla säteellä',
'sv': 'En cirkel med medelpunkt och radie från två punkter / en sträcka'
}
});
/** GeoToolTriangle ******/
Localizer.addTerms({
'Triangle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first cornerpoint</strong> of triangle.</p>',
'fi': '<p>Valitse tai lisää kolmion <strong>ensimmäinen kulmapiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till triangelns <strong>första hörnpunkt</strong>.</p>'
},
'Triangle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>second cornerpoint</strong> of triangle.</p>',
'fi': '<p>Valitse tai lisää kolmion <strong>toinen kulmapiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till triangelns <strong>andra hörnpunkt</strong>.</p>'
},
'Triangle-2': {
'en': '<p>Click on the drawing area to select or to add the <strong>third cornerpoint</strong> of triangle.</p>',
'fi': '<p>Valitse tai lisää kolmion <strong>kolmas kulmapiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till triangelns <strong>tredje hörnpunkt</strong>.</p>'
},
'Triangle-maintooltip': {
'en': 'Triangle',
'fi': 'Kolmio',
'sv': 'Triangel'
},
'Triangle-tooltip': {
'en': 'Triangle',
'fi': 'Kolmio',
'sv': 'Triangel'
}
});
/** GeoToolRighttriangle ********/
Localizer.addTerms({
'Righttriangle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first end of hypotenuse</strong>.</p>',
'fi': '<p>Valitse tai lisää <strong>hypotenuusan ensimmäinen päätepiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>första ändpunkten för hypotenusan</strong>.</p>'
},
'Righttriangle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>second end of hypotenuse</strong>.</p>',
'fi': '<p>Valitse tai lisää <strong>hypotenuusan toinen päätepiste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>andra ändpunkten för hypotenusan</strong>.</p>'
},
'Righttriangle-2': {
'en': '<p>Click on the drawing area to select or to add the <strong>third</strong> cornerpoint of right triangle.</p>',
'fi': '<p>Valitse tai lisää suorakulmaisen kolmion <strong>kolmas</strong> kulmapiste klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>tredje</strong> hörnpunkten för den rätvinkliga triangeln.</p>'
},
'Righttriangle-tooltip': {
'en': 'Right triangle - hypotenuse first',
'fi': 'Suorakulmainen kolmio - hypotenuusa ensin',
'sv': 'Rätvinklig triangel - hypotenusan i den första'
}
});
/** GeoToolGlider *******/
Localizer.addTerms({
'Glider-start': {
'en': '<p>Click on a curve to add a new glider.</p>',
'fi': '<p>Lisää uusi liukuva piste klikkaamalla käyrää.</p>',
'sv': '<p>Klicka på kurvan för att lägga till en ny glidare.</p>'
},
'Glider-tooltip': {
'en': 'Glider point',
'fi': 'Liukuva piste',
'sv': 'En glidande punkt'
}
});
/** GeoToolMidpoint *******/
Localizer.addTerms({
'Midpoint-start': {
'en': '<p>Click on a <strong>segment or the first end point</strong> of segment to add a midpoint.</p>',
'fi': '<p>Lisää janalle keskipiste klikkaamalla <strong>janaa tai janan alkupään pistettä</strong>.</p>'
},
'Midpoint-1': {
'en': '<p>Click on <strong>the second end point of</strong> of a segment to add a midpoint.</p>',
'fi': '<p>Klikkaa janan <strong>toista päätepistettä</strong> keskipisteen lisäämiseksi.</p>'
},
'Midpoint-error-0': {
'en': '<p>You didn\'t click a point or a segment.</p><p>Click on a <strong>segment or the first end point</strong> of a segment to add a midpoint.</p>',
'fi': '<p>Et osunut pisteeseen tai janaan.</p><p>Lisää janalle keskipiste klikkaamalla <strong>janaa tai janan alkupään pistettä</strong>.</p>'
},
'Midpoint-error-1': {
'en': '<p>You didn\'t click a point.</p><p>Click on <strong>the second end point of</strong> of a segment to add a midpoint.</p>',
'fi': '<p>Et osunut pisteeseen.</p><p>Klikkaa janan <strong>toista päätepistettä</strong> keskipisteen lisäämiseksi.</p>'
},
'Midpoint-tooltip': {
'en': 'Midpoint',
'fi': 'Keskipiste'
}
});
/** GeoToolIntersection *****/
Localizer.addTerms({
'Intersection-start': {
'en': '<p>Click on the first curve.</p>',
'fi': '<p>Klikkaa ensimmäistä käyrää</p>',
'sv': '<p>Klicka på första kurvan</p>'
},
'Intersection-1': {
'en': '<p>Click on the second curve.</p>',
'fi': '<p>Klikkaa toista käyrää</p>',
'sv': '<p>Klicka på andra kurvan</p>'
},
'Intersection-tooltip': {
'en': 'Intersection points',
'fi': 'Leikkauspisteet',
'sv': 'Skärningspunkterna'
}
});
/** GeoToolNormal *******/
Localizer.addTerms({
'Normal-start': {
'en': '<p>Click on the drawing area to select the <strong>curve</strong> you want to draw a normal for.</p>',
'fi': '<p>Valitse piirtoaluetta klikkaamalla <strong>käyrä</strong>, jolle haluat piirtää normaalin.</p>',
'sv': '<p>Klicka på <strong>kurvan</strong> på ritområdet för att rita en normal till kurvan.</p>',
},
'Normal-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>point</strong> the normal will go through.</p>',
'fi': '<p>Valitse tai lisää piirtoaluetta klikkaamalla <strong>piste</strong>, jonka kautta normaali kulkee.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>punkt</strong> som normalen går genom.</p>'
},
'Normal-error-0': {
'en': '<p>You missed the curve. Click on the drawing area to select the <strong>curve</strong> you want to draw a normal for.</p>',
'fi': '<p>Et osunut käyrään. Valitse piirtoaluetta klikkaamalla <strong>käyrä</strong>, jolle haluat piirtää normaalin.</p>',
'sv': '<p>Du träffade inte kurvan. Välj den <strong>kurva</strong> du vill rita en normal till genom att klicka på ritområdet.</p>'
},
'Normal-tooltip': {
'en': 'Normal',
'fi': 'Normaali',
'sv': 'Normal',
}
});
/** GeoToolParallel *****/
Localizer.addTerms({
'Parallel-start': {
'en': '<p>Click on the drawing area to select the <strong>line or segment</strong> with which you want to draw a parallel line.</p>',
'fi': '<p>Valitse piirtoaluetta klikkaamalla <strong>suora tai jana</strong>, jonka kanssa yhdensuuntaisen suoran haluat piirtää.</p>'
},
'Parallel-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>point</strong> the parallel line will go through.</p>',
'fi': '<p>Valitse tai lisää piirtoaluetta klikkaamalla <strong>piste</strong>, jonka kautta yhdensuuntainen suora kulkee.</p>'
},
'Parallel-error-0': {
'en': '<p>You missed the line. Click on the drawing area to select the <strong>line or segment</strong> with which you want to draw a parallel line.</p>',
'fi': '<p>Et osunut käyrään. Valitse piirtoaluetta klikkaamalla <strong>suora tai jana</strong>, jonka kanssa yhdensuuntaisen suoran haluat piirtää.</p>'
},
'Parallel-tooltip': {
'en': 'Parallel line',
'fi': 'Yhdensuuntainen suora'
}
});
/** GeoToolTangent ********/
Localizer.addTerms({
'Tangent-start': {
'en': '<p>Click on the drawing area to select the <strong>curve</strong> you want to draw a tangent(s) for.</p>',
'fi': '<p>Valitse piirtoaluetta klikkaamalla <strong>käyrä</strong>, jolle haluat piirtää tangentin.</p>'
},
'Tangent-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>point</strong> the tangent will go through.</p>',
'fi': '<p>Valitse tai lisää piirtoaluetta klikkaamalla <strong>piste</strong>, jonka kautta tangentti kulkee.</p>'
},
'Tangent-error-0': {
'en': '<p>You missed the curve. Click on the drawing area to select the <strong>curve</strong> you want to draw a tangent(s) for.</p>',
'fi': '<p>Et osunut käyrään. Valitse piirtoaluetta klikkaamalla <strong>käyrä</strong>, jolle haluat piirtää tangentin.</p>'
},
'Tangent-tooltip': {
'en': 'Normal',
'fi': 'Normaali'
}
});
/** GeoToolRectangle *********/
Localizer.addTerms({
'Rectangle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first point</strong> of the rectangle.</p>',
'fi': '<p>Valitse tai lisää <strong>suorakaiteen ensimmäinen piste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>första punkten</strong> av rektangeln.</p>',
},
'Rectangle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>second point</strong> of the rectangle.</p>',
'fi': '<p>Valitse tai lisää <strong>suorakaiteen toinen piste</strong> klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>andra punkten</strong> av rektangeln.</p>',
},
'Rectangle-2': {
'en': '<p>Click on the drawing area to select or to add the <strong>third cornerpoint</strong> of the rectangle.</p>',
'fi': '<p>Valitse tai lisää suorakaiteen <strong>kolmas</strong> kulmapiste klikkaamalla piirtoaluetta.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till den <strong>tredje hörnpunkten</strong> av rektangeln.</p>',
},
'Rectangle-maintooltip': {
'en': 'Rectangle',
'fi': 'Suorakaide',
'sv': 'Rektangel'
},
'Rectangle-tooltip': {
'en': 'Rectangle',
'fi': 'Suorakaide',
'sv': 'Rektangel'
}
});
/** GeoToolRtriangle **********/
Localizer.addTerms({
'Rtriangle-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first point</strong> of the right triangle.</p>',
'fi': '<p>Valitse tai lisää <strong>suorakulmaisen kolmion ensimmäinen piste</strong> klikkaamalla piirtoaluetta.</p>'
},
'Rtriangle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>point in the right angle corner</strong> of the right triangle.</p>',
'fi': '<p>Valitse tai lisää suorakulmaisen kolmion <strong>suorakulmaisen kulman piste</strong> klikkaamalla piirtoaluetta.</p>'
},
'Rtriangle-2': {
'en': '<p>Click on the drawing area to select or to add the <strong>third cornerpoint</strong> of the right triangle.</p>',
'fi': '<p>Valitse tai lisää suorakulmaisen kolmion <strong>kolmas kulmapiste</strong> klikkaamalla piirtoaluetta.</p>'
},
'Rtriangle-maintooltip': {
'en': 'Right triangle',
'fi': 'Suorakulmainen kolmio'
},
'Rtriangle-tooltip': {
'en': 'Right triangle - catheti first',
'fi': 'Suorakulmainen kolmio - kateetti ensin'
}
});
/** GeoToolAngle *********/
Localizer.addTerms({
'Angle-start': {
'en': '<p>Click on the drawing area to select or to add the point on the <strong>right hand side</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kulman <strong>oikean sivun</strong> piste.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till punkten på den <strong>högra sidan</strong> av vinkeln.</p>'
},
'Angle-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>corner point</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kulman <strong>kärkipiste</strong>.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till vinkelns <strong>spetspunkt</strong> </p>'
},
'Angle-2': {
'en': '<p>Click on the drawing area to select or to add the point on the <strong>left hand side</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kolmion <strong>vasemman sivun</strong> piste.</p>',
'sv': '<p>Klicka på ritområdet för att välja eller lägga till punkten på den <strong>vänstra sidan</strong> av vinkeln.</p>'
},
'Angle-maintooltip': {
'en': 'Angles',
'fi': 'Kulmat',
'sv': 'Vinklar'
},
'Angle-tooltip': {
'en': 'Angle',
'fi': 'Kulma',
'sv': 'Vinkel'
}
});
/** GeoToolBisector *********/
Localizer.addTerms({
'Bisector-start': {
'en': '<p>Click on the drawing area to select or to add the point on the <strong>right hand side</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kulman <strong>oikean kyljen</strong> piste.</p>'
},
'Bisector-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>corner point</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kulman <strong>kärkipiste</strong>.</p>'
},
'Bisector-2': {
'en': '<p>Click on the drawing area to select or to add the point on the <strong>left hand side</strong> of the angle.</p>',
'fi': '<p>Valitse tai lisää kulman <strong>vasemman kyljen</strong> piste.</p>'
},
'Bisector-maintooltip': {
'en': 'Bisector',
'fi': 'Kulmanpuolittaja'
},
'Bisector-tooltip': {
'en': 'Bisector',
'fi': 'Kulmanpuolittaja'
}
});
/** GeoToolParallelogram *********/
Localizer.addTerms({
'Parallelogram-start': {
'en': '<p>Click on the drawing area to select or to add the <strong>first cornerpoint</strong> of parallelogram.</p>',
'fi': '<p>Valitse tai lisää suunnikkaan <strong>ensimmäinen kulmapiste</strong> klikkaamalla piirtoaluetta.</p>'
},
'Parallelogram-1': {
'en': '<p>Click on the drawing area to select or to add the <strong>second cornerpoint</strong> of parallelogram.</p>',
'fi': '<p>Valitse tai lisää suunnikkaan <strong>toinen kulmapiste</strong> klikkaamalla piirtoaluetta.</p>'
},
'Parallelogram-2': {
'en': '<p>Click on the drawing area to select or to add the <strong>third</strong> cornerpoint of parallelogram.</p>',
'fi': '<p>Valitse tai lisää suunnikkaan <strong>kolmas</strong> kulmapiste klikkaamalla piirtoaluetta.</p>'
},
'Parallelogram-maintooltip': {
'en': 'Parallelogram',
'fi': 'Suunnikas'
},
'Parallelogram-tooltip': {
'en': 'Parallelogram',
'fi': 'Suunnikas'
}
});
/** GeoToolLabel ******/
Localizer.addTerms({
'Label-start': {
'en': '<p>Click on the drawing area to add a label.</p>',
'fi': '<p>Lisää teksti klikkaamalla piirtoaluetta.</p>'
},
'Label-maintooltip': {
'en': 'Text label',
'fi': 'Teksti',
'sv': 'Text'
},
'Label-tooltip': {
'en': 'Text label',
'fi': 'Teksti',
'sv': 'Text'
}
});
}
{ /*** GeoScene ***************************************************************/
/**
* Constructor for geometric scene.
*/
var GeoScene = function(params) {
params = $.extend( {
'objects' : [],
'boundingBox' : [-10, 5, 10, -5],
'description' : '',
'name' : '',
'showGrid' : false,
'showAxis' : false,
'isStatic' : false,
'allowControls' : true,
'decimalperiod': this.decimalperiod || false,
'geoid': null
}, params);
this.type = 'Scene';
this.geoid = params.geoid;
this.lang = params.lang;
this.decimalperiod = params.decimalperiod;
this.objects = [];
this.objectsById = {};
for (var i = 0; i < params.objects.length; i++) {
this.add(this.dataToObject(params.objects[i]));
}
this.name = params.name;
this.boundingBox = params.boundingBox;
this.description = params.description;
this.showGrid = params.showGrid;
this.showAxis = params.showAxis;
this.isStatic = params.isStatic;
this.allowControls = params.allowControls;
}
/**
* Icon for GeoScene
*/
GeoScene.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-scene"><rect x="2" y="2" width="16" height="16" style="stroke: black; fill: none;" /><line x1="2" y1="6" x2="18" y2="6" style="stroke: black;" /><line x1="2" y1="10" x2="18" y2="10" style="stroke: black;" /><line x1="2" y1="14" x2="18" y2="14" style="stroke: black;" /><line x1="6" y1="2" x2="6" y2="18" style="stroke: black;" /><line x1="10" y1="2" x2="10" y2="18" style="stroke: black;" /><line x1="14" y1="2" x2="14" y2="18" style="stroke: black;" /></svg>';
/**
* Get list of objects.
*/
GeoScene.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname">' + this.name + '</div>';
return str;
}
/**
* Get list of objects.
*/
GeoScene.prototype.getObjectlist = function(){
var objlist = [];
for (var i = 0; i < this.objects.length; i++) {
var currObj = this.objects[i];
objlist.push(currObj.getListData());
}
return objlist;
}
/**
* Return true, if the scene has an object with this id.
*/
GeoScene.prototype.hasObject = function(geoid){
return (typeof(this.objectsById[geoid]) !== 'undefined');
}
/**
* Get data of GeoScene
*/
GeoScene.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
objects: [],
boundingBox: this.boundingBox.slice(), // Copy, not original!
description: this.description,
showGrid: this.showGrid,
showAxis: this.showAxis,
isStatic: this.isStatic,
allowControls: this.allowControls
};
for (var i = 0; i < this.objects.length; i++) {
data.objects.push(this.objects[i].getData());
}
return data;
}
/**
* Return name of object with given geoid.
*/
GeoScene.prototype.getObjName = function(geoid){
return this.objectsById[geoid] && this.objectsById[geoid].nameStr() || '';
}
/**
* Get recoursively all objects depending on object in given array.
*/
GeoScene.prototype.getDependents = function(geoids){
var dependents = [];
for (var i = 0; i < geoids.length; i++) {
var deplist = this.getDependentObjs(geoids[i]);
for (var j = 0; j < deplist.length; j++) {
if (dependents.indexOf(deplist[j]) === -1) {
dependents.push(deplist[j]);
}
}
}
return dependents;
}
/**
* Get recoursively all objects depending on object with given geoid.
*/
GeoScene.prototype.getDependentObjs = function(geoid){
var dependents = [];
for (var i = 0; i < this.objects.length; i++) {
var gid = this.objects[i].getId();
var deps = this.objects[i].getDeps();
var index = deps.indexOf(geoid);
if (index !== -1 && dependents.indexOf(gid) === -1) {
dependents.push(gid);
}
}
for (var i = 0; i < dependents.length; i++) {
var subdeps = this.getDependentObjs(dependents[i]);
for (var j = 0; j < subdeps.length; j++) {
if (dependents.indexOf(subdeps[j]) === -1) {
dependents.push(subdeps[j]);
}
}
}
return dependents;
}
/**
* Update given objects from board.
*/
GeoScene.prototype.updateFromBoard = function(geoids){
if (geoids.length > 0) {
for (var i = 0; i < geoids.length; i++) {
this.objectsById[geoids[i]] && this.objectsById[geoids[i]].updateFromBoard(this.board);
}
} else {
for (var i = 0, len = this.objects.length; i < len; i++) {
this.objects[i].updateFromBoard(this.board);
}
}
}
/**
* Get data of given object.
*/
GeoScene.prototype.getObjData = function(objId){
var result;
var parts = objId.split('-');
var geoid = parts[0];
var subid = parts[1];
if (this.objectsById[geoid]) {
result = this.objectsById[geoid].getData(subid);
} else {
result = null;
}
return result;
}
/**
* Set data of given object.
*/
GeoScene.prototype.setObjData = function(objId, data){
if (objId === 'scene') {
this.name = (typeof data.name !== 'undefined' ? data.name : this.name);
this.description = (typeof data.description !== 'undefined' ? data.description : this.description);
this.showGrid = (typeof(data.showGrid) !== 'undefined' ? data.showGrid : this.showGrid);
this.showAxis = (typeof(data.showAxis) !== 'undefined' ? data.showAxis : this.showAxis);
this.isStatic = (typeof(data.isStatic) !== 'undefined' ? data.isStatic : this.isStatic);
this.allowControls = (typeof(data.allowControls) !== 'undefined' ? data.allowControls : this.allowControls);
this.boundingBox[0] = (typeof(data.boundingBox0) !== 'undefined' ? this.strToNum(data.boundingBox0) : this.boundingBox[0]);
this.boundingBox[1] = (typeof(data.boundingBox1) !== 'undefined' ? this.strToNum(data.boundingBox1) : this.boundingBox[1]);
this.boundingBox[2] = (typeof(data.boundingBox2) !== 'undefined' ? this.strToNum(data.boundingBox2) : this.boundingBox[2]);
this.boundingBox[3] = (typeof(data.boundingBox3) !== 'undefined' ? this.strToNum(data.boundingBox3) : this.boundingBox[3]);
} else {
this.objectsById[objId].setData(data);
}
}
/**
* Move the bounding box of scene.
*/
GeoScene.prototype.move = function(direction){
var width = this.boundingBox[2] - this.boundingBox[0];
var height = this.boundingBox[1] - this.boundingBox[3];
var dx = width / 8;
var dy = height /8;
switch (direction) {
case 'up':
this.boundingBox[1] += dy;
this.boundingBox[3] += dy;
break;
case 'down':
this.boundingBox[1] -= dy;
this.boundingBox[3] -= dy;
break;
case 'left':
this.boundingBox[0] -= dx;
this.boundingBox[2] -= dx;
break;
case 'right':
this.boundingBox[0] += dx;
this.boundingBox[2] += dx;
break;
default:
break;
}
}
/**
* Zoom the bounding box of scene.
*/
GeoScene.prototype.zoom = function(direction){
var width = this.boundingBox[2] - this.boundingBox[0];
var height = this.boundingBox[1] - this.boundingBox[3];
switch (direction) {
case 'out':
var dx = width / 8;
var dy = height /8;
this.boundingBox[0] -= dx;
this.boundingBox[1] += dy;
this.boundingBox[2] += dx;
this.boundingBox[3] -= dy;
break;
case 'in':
var dx = width / 10;
var dy = height /10;
this.boundingBox[0] += dx;
this.boundingBox[1] -= dy;
this.boundingBox[2] -= dx;
this.boundingBox[3] += dy;
break;
default:
break;
}
}
/**
* Get aspect ratio of the bounding box.
*/
GeoScene.prototype.getAspectRatio = function(){
return (this.boundingBox[2] - this.boundingBox[0]) / (this.boundingBox[1] - this.boundingBox[3]);
}
/**
* Get caption text.
*/
GeoScene.prototype.getCaption = function(){
return this.description;
}
/**
* Get dialog object from GeoScene
*/
GeoScene.prototype.getDialog = function(objid){
var dialog = {};
if (objid === 'scene') {
dialog.basic = [
{
type: 'Text',
label: 'Name',
key: 'name',
value: this.name
},
{
type: 'Textbox',
label: 'Description',
key: 'description',
value: this.description
}
];
dialog.advanced = [
{
type: 'Checkbox',
label: 'Show grid',
key: 'showGrid',
value: this.showGrid
},
{
type: 'Checkbox',
label: 'Show axis',
key: 'showAxis',
value: this.showAxis
},
{
type: 'Checkbox',
label: 'Static',
key: 'isStatic',
value: this.isStatic
},
{
type: 'Checkbox',
label: 'Allow controls',
key: 'allowControls',
value: this.allowControls
},
{
type: 'Boxarea',
label: 'Bounding box',
key: ['boundingBox1', 'boundingBox0', 'boundingBox2', 'boundingBox3'],
value: [
this.numToStr(this.boundingBox[1]),
this.numToStr(this.boundingBox[0]),
this.numToStr(this.boundingBox[2]),
this.numToStr(this.boundingBox[3])
]
}
];
} else if (typeof objid !== 'undefined'){
dialog = this.objects[objid].getOptionsDialog();
}
return dialog;
}
/**
* Get the list of all objects of given type (ids).
**/
GeoScene.prototype.getOfType = function(otype){
var list = [];
for (var i = 0; i < this.objects.length; i++) {
var obj = this.objects[i];
var typeobjs = obj.getOfType(otype);
list = list.concat(typeobjs);
}
return list;
}
/**
* Get the list of all points (ids).
**/
GeoScene.prototype.getPoints = function(){
return this.getOfType('Point');
}
/**
* Get the list of all point like objects (ids). (Points, Gliders,...)
**/
GeoScene.prototype.getPointlikes = function(){
var pointtypes = ['Point', 'Glider', 'Intersection', 'Midpoint'];
var pointlist = [];
for (var i = 0; i < pointtypes.length; i++) {
pointlist = pointlist.concat(this.getOfType(pointtypes[i]));
}
pointlist.sort(function(a,b){return (a.name < b.name ? -1 : 1);});
return pointlist;
}
/**
* Get the list of all curves (ids). (Lines, Circles,...)
**/
GeoScene.prototype.getCurves = function(){
var curvetypes = ['Line', 'Circle', 'Linelike','Triangle','Bisector'];
var curvelist = [];
for (var i = 0; i < curvetypes.length; i++) {
curvelist = curvelist.concat(this.getOfType(curvetypes[i]));
}
return curvelist;
}
/**
* Create and add new object from data.
*/
GeoScene.prototype.addObject = function(data){
return this.add(this.dataToObject(data));
}
/**
* Convert data to a GeoObject
*/
GeoScene.prototype.dataToObject = function(params){
var newelement;
params.decimalperiod = this.decimalperiod;
switch (params.type){
case 'Label':
newelement = new GeoLabel(params, this);
break;
case 'Point':
newelement = new GeoPoint(params, this);
break;
case 'Line':
newelement = new GeoLine(params, this);
break;
case 'Circle':
newelement = new GeoCircle(params, this);
break;
case 'Rcircle':
newelement = new GeoRcircle(params, this);
break;
case 'Glider':
newelement = new GeoGlider(params, this);
break;
case 'Midpoint':
newelement = new GeoMidpoint(params, this);
break;
case 'Intersection':
newelement = new GeoIntersection(params, this);
break;
case 'Triangle':
newelement = new GeoTriangle(params, this);
break;
case 'Righttriangle':
newelement = new GeoRighttriangle(params, this);
break;
case 'Rtriangle':
newelement = new GeoRtriangle(params, this);
break;
case 'Angle':
newelement = new GeoAngle(params, this);
break;
case 'Bisector':
newelement = new GeoBisector(params, this);
break;
case 'Normal':
newelement = new GeoNormal(params, this);
break;
case 'Parallel':
newelement = new GeoParallel(params, this);
break;
case 'Tangent':
newelement = new GeoTangent(params, this);
break;
case 'Rectangle':
newelement = new GeoRectangle(params, this);
break;
case 'Parallelogram':
newelement = new GeoParallelogram(params, this);
break;
default:
newelement = false;
}
return newelement;
}
/**
* Add given GeoObject to scene.
*/
GeoScene.prototype.add = function(data){
if (data && !this.objectsById[data.geoid]) {
this.objects.push(data);
this.objectsById[data.geoid] = data;
} else {
alert('ei ollu: '+data.geoid);
}
return data.geoid;
}
/**
* Remove GeoObject from scene.
*/
GeoScene.prototype.removeObject = function(objectId){
var geoid = this.objects[objectId].getId();
this.objects.splice(objectId, 1);
delete this.objectsById[geoid];
}
/**
* Toggle visibility of GeoObject.
*/
GeoScene.prototype.toggleVisible = function(objectId){
this.objects[objectId].toggleVisible();
}
/**
* Deselect object with given id.
*/
GeoScene.prototype.deselectObject = function(geoid){
if (geoid && geoid !== 'scene' && this.objectsById[geoid]) {
this.objectsById[geoid].deselect(this.board);
}
}
/**
* Select object with given id.
*/
GeoScene.prototype.selectObject = function(geoid){
if (geoid && geoid !== 'scene' && this.objectsById[geoid]) {
this.objectsById[geoid].select(this.board);
}
}
/**
* Draw the scene to the html-element with given id.
*/
GeoScene.prototype.draw = function(viewid, readonly){
var scene = this;
this.board = JXG.JSXGraph.initBoard(
viewid,
{
boundingbox: this.boundingBox,
keepaspectratio:true,
grid: this.showGrid,
axis: this.showAxis,
showCopyright: false,
showNavigation: false,
zoom: false/*sceneArr[sceneNum].allowControls && (!sceneArr[sceneNum].isStatic)*/,
pan: (this.allowControls && (!this.isStatic))
}
);
var getMouseCoords = function(event) {
var cPos = scene.board.getCoordsTopLeftCorner(event),
absPos = JXG.getPosition(event),
dx = absPos[0]-cPos[0],
dy = absPos[1]-cPos[1];
return new JXG.Coords(JXG.COORDS_BY_SCREEN, [dx, dy], scene.board);
}
var down = function(e) {
var coords = getMouseCoords(e);
var data = {xcoord: coords.usrCoords[1], ycoord: coords.usrCoords[2], board: scene.board};
$(scene.board.containerObj).trigger('clickonboard', [data]);
}
var mousecursor = scene.board.create('Point', [1,0,0], {visible: false, name: 'gedithiddenmousecursor', face: 'x'});
var cursorMove = function(e){
var coords = getMouseCoords(e);
mousecursor.moveTo([coords.usrCoords[1], coords.usrCoords[2]], 0);
}
this.board.on('mousemove', cursorMove);
this.board.on('down', down);
if (readonly && this.isStatic){
this.board.removeEventHandlers();
}
this.construction = this.board.construct('');
var objlist = this.objects.slice(0).reverse();
var len = objlist.length + 1;
while (len > objlist.length){
len = objlist.length;
for (var i = len -1; i > -1; i--) {
if (objlist[i].drawable(this.board)) {
objlist[i].asConstruct(this.board, this.construction);
objlist.splice(i, 1);
} else {
}
}
}
var errors = [];
for (var i = 0; i < objlist.length; i++) {
errors.push(objlist[i].getId());
}
return errors;
}
/**
* Convert number to text. (Localize decimal period etc.)
*/
GeoScene.prototype.numToStr = function(num){
var str = ''+num;
if (this.decimalperiod) {
str = str.replace(/\./g, ',');
}
return str;
}
/**
* Convert text to number. (With localization (decimal period etc.))
*/
GeoScene.prototype.strToNum = function(str){
var num = str;
if (typeof str === 'string') {
num = parseFloat(str.replace(/,/g, '.'));
}
return num;
}
/**
* Send updateinfo-event with message.
**/
GeoScene.prototype.sendInfo = function(message){
$(this.board.containerObj).trigger('updateinfo', [message]);
}
/**
* Show caption
***/
GeoScene.prototype.showCaption = function(){
var message = this.getCaption();
message = '<p>' + message.split('\n').join('</p><p>') + '</p>';
this.sendInfo(message);
}
} // End GeoScene
{ /*** GeoData ****************************************************************/
{ // GeoObject
/**
* GeoObject - a virtual class that can be inherited.
*/
var GeoObject = function(params, geoparent){
this.type = 'GeoObject';
this.decimalperiod = false;
}
/**
* Get list string (to be shown in the object list)
**/
GeoObject.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname">' + this.getNameFormatted() + '</div>';
return str;
}
/**
* Get list data (to be shown in the object list)
**/
GeoObject.prototype.getListData = function(){
var data = {
str: this.getListStr(),
geoid: this.getId(),
visible: this.visible
}
return data;
}
/**
* Get objects data
**/
GeoObject.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid
}
return data;
}
/**
* Get objects id.
**/
GeoObject.prototype.getId = function(){
return this.geoid;
}
/**
* Get objects name.
**/
GeoObject.prototype.getName = function(){
return this.name;
}
/**
* Get the list of dependencies.
**/
GeoObject.prototype.getDeps = function(){
return [];
}
/**
* Get the name of object with given geoid.
**/
GeoObject.prototype.getObjName = function(geoid){
return this.geoparent.getObjName(geoid);
}
/**
* Get list of elements of given type.
**/
GeoObject.prototype.getOfType = function(otype){
return [];
}
/**
* Toggle visibility of this GeoObject.
**/
GeoObject.prototype.toggleVisible = function(){
this.visible = !this.visible;
}
/**
* Update data of the object from the board.
**/
GeoObject.prototype.updateFromBoard = function(board){
// By default do nothing.
}
/**
* Find requested point from construction by the name.
**/
GeoObject.prototype.findPointByName = function(name_Str, construction){
var j = -1;
do ++j; while ((j < construction.points.length) && (name_Str !== construction.points[j].name));
var p1 = null;
if (j < construction.points.length) {
p1 = construction.points[j];
}
else {
j = -1;
do ++j; while ( (j < construction.intersections.length) && (name_Str != construction.intersections[j].name) );
if (j < construction.intersections.length) p1 = construction.intersections[j];
}
return p1;
}
/**
* Get the formatted name of the GeoObject.
*/
GeoObject.prototype.getNameFormatted = function() {
var str = this.nameStr();
str = str.replace(/_\{([^\}]+)\}/g, '<sub>$1</sub>').replace(/_([^{}])/g, '<sub>$1</sub>');
return str;
}
/**
* Get the nameStr of the GeoObject.
*/
GeoObject.prototype.nameStr = function() {
var result = this.name;
for (var property in this) {
result = result.replace(new RegExp('%' + property + '%', 'g'), this[property]);
}
return result;
}
/**
* Select this object.
**/
GeoObject.prototype.select = function(board){
if (board.objects[this.geoid]) {
board.objects[this.geoid].setProperty({shadow: true});
}
}
/**
* Deselect this object.
**/
GeoObject.prototype.deselect = function(board){
if (board.objects[this.geoid]) {
board.objects[this.geoid].setProperty({shadow: false});
}
}
/**
* Convert a GeoObject to JessieScript.
*/
GeoObject.prototype.asJessieScript = function() { /* Not used. */ return ""; }
/**
* Tell, if the GeoObject is drawable.
*/
GeoObject.prototype.drawable = function(board){
return true;
}
/**
* Convert number to text. (Localize decimal period etc.)
*/
GeoObject.prototype.numToStr = function(num){
var str = ''+num;
if (this.decimalperiod) {
str = str.replace(/\./g, ',');
}
return str;
}
/**
* Convert text to number. (With localization (decimal period etc.))
*/
GeoObject.prototype.strToNum = function(str){
var num = str;
if (typeof str === 'string') {
num = parseFloat(str.replace(/,/g, '.')) || 0;
}
num = Math.round(num * 100) / 100;
return num;
}
GeoObject.prototype.dashTypes = [
"–––––––––",
"..................",
"-------------",
"- - - - - - - -",
"– – – – – –",
"- – - – -",
"- – - – - – -"
];
} // End GeoObject
{ // GeoPoint
/**
* Constructor for geometric point object.
*/
var GeoPoint = function(params, geoparent) {
this.type = 'Point';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoPoint.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoPoint.prototype.setData = function(params){
params = $.extend( {
'x' : (typeof(this.x) !== 'undefined' ? this.x : null),
'y' : (typeof(this.y) !== 'undefined' ? this.y : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'fixed' : this.fixed || false,
'size' : (typeof this.size !== 'undefined' ? this.size : 3),
'color' : this.color || '#ff0000',
'snapToGrid' : this.snapToGrid || false,
'decimalperiod' : this.decimalperiod || false
}, params);
this.size = this.strToNum(params.size);
this.x = this.strToNum(params.x);
this.y = this.strToNum(params.y);
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
this.snapToGrid = params.snapToGrid;
this.decimalperiod = params.decimalperiod;
}
/**
* Get data of GeoPoint
**/
GeoPoint.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
x: this.x,
y: this.y,
showName: this.showName,
visible: this.visible,
fixed: this.fixed,
size: this.size,
color: this.color,
snapToGrid: this.snapToGrid
}
return data;
}
/**
* CSS style defining the icon representing this type.
**/
GeoPoint.prototype.iconCSS = 'pointBtn';
GeoPoint.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="geoedit-icon geoedit-object-point"><circle style="stroke: none; fill: red;" cx="15" cy="15" r="5" /></svg>';
/**
* Draw the point on board in the construction.
*/
GeoPoint.prototype.asConstruct = function(board, construction) {
var geopoint = this;
var obj = this;
var p = board.create(
'point',
[this.x, this.y],
{
name : this.name,
id : this.geoid,
size : this.size,
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
strokeColor: (!this.fixed ? this.color : '#000000'),
fillColor: (!this.fixed ? this.color : '#000000'),
snapToGrid: this.snapToGrid
}
);
if (!this.name) {
this.name = p.name;
}
//this.id = this.id || p.id;
p.obj = obj;
construction.points.push(p);
construction[this.name] = p;
if (this.showName){
p.label.content.setText(this.nameStr(construction));
}
p.on('up', function(event){
var point = this;
var updoptions = {name: geopoint.name, geoid: [geopoint.geoid]};
$(point.board.containerObj).trigger('objectupdate', [updoptions]);
var options = {
name: geopoint.name,
x: Math.round(point.X() * 100)/100,
y: Math.round(point.Y() * 100)/100,
element: geopoint
};
//$(point.board.containerObj).trigger('objectmoved', [options]);
$(point.board.containerObj).trigger('objectupdate', [options]);
});
p.on('down', function(event){
var point = this;
var options = {name: geopoint.name, geoid: geopoint.geoid, delay: true};
$(point.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Update data of the object from the board.
**/
GeoPoint.prototype.updateFromBoard = function(board){
var point = board.objects[this.geoid];
this.x = Math.round(point.X() * 100)/100;
this.y = Math.round(point.Y() * 100)/100;
}
/**
* Get list of elements of given type.
**/
GeoPoint.prototype.getOfType = function(otype){
var list = [];
if (otype === 'Point') {
list.push({id: this.geoid, name: this.name});
}
return list;
}
/**
* Get the object for options dialog.
*/
GeoPoint.prototype.getOptionsDialog = function() {
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Text',
label: 'x-coordinate',
key: 'x',
value: this.numToStr(this.x)
},
{
type: 'Text',
label: 'y-coordinate',
key: 'y',
value: this.numToStr(this.y)
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Fixed',
key: 'fixed',
value: this.fixed
},
{
type: 'Checkbox',
label: 'Snap to grid',
key: 'snapToGrid',
value: this.snapToGrid
},
{
type: 'Text',
label: 'Size',
key: 'size',
value: this.size
}
]
}
return dialog;
}
} // End GeoPoint
{ // GeoLine
/**
* Constructor for geometric line object.
*/
var GeoLine = function(params, geoparent) {
this.type = 'Line';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoLine.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoLine.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || '',
'p2' : this.p2 || '',
'firstArrow' : this.firstArrow || false,
'lastArrow' : this.lastArrow || false,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'lineType' : this.lineType || 'lineSegment',
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.visible) !== 'undefined' ? this.visible : true),
'color' : this.color || '#0000ff',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2),
'labelOffset' : [10, 10]
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.firstArrow = params.firstArrow;
this.lastArrow = params.lastArrow;
this.name = params.name;
this.dash = params.dash;
this.lineType = params.lineType;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
this.labelOffset = params.labelOffset;
this.lang = params.lang;
}
/**
* Get data of GeoLine
**/
GeoLine.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
firstArrow: this.firstArrow,
lastArrow: this.lastArrow,
dash: this.dash,
lineType: this.lineType,
showName: this.showName,
visible: this.visible,
color: this.color,
strokeWidth: this.strokeWidth,
labelOffset: this.labelOffset
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoLine.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoLine.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>l</i>(<i>'+this.getObjName(this.p1)+'</i>,<i>'+this.getObjName(this.p2)+'</i>)</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoLine.prototype.iconCSS = 'lineBtn';
GeoLine.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-line"><line style="stroke: blue;" x1="0" y1="4" x2="20" y2="17" /><circle style="stroke: none; fill: red;" cx="4.5" cy="7" r="2" /><circle style="stroke: none; fill: red;" cx="15" cy="14" r="2" /></svg>';
/**
* Draw the line on board in the construction.
**/
GeoLine.prototype.asConstruct = function(board, construction) {
var geoline = this;
var line = board.create(
'line',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : false,
straightFirst : ((this.lineType === 'line') || (this.lineType === 'startingLine')),
straightLast : ((this.lineType === 'line') || (this.lineType === 'endingLine')),
firstArrow : this.firstArrow,
lastArrow : this.lastArrow,
dash : this.dash,
strokeWidth : this.strokeWidth,
color : this.color,
label : {
fixed : false
}
}
);
var labelPoint = board.create(
'point',
[
function (){ return ((line.point1.X() + line.point2.X()) / 2); },
function (){ return ((line.point1.Y() + line.point2.Y()) / 2); }
],
{
// Options here.
visible : this.visible,
fixed : true,
name : 'labelOf' + this.name,
withLabel : this.showName,
isLabel : true,
size : -1,
label : {
offset : this.labelOffset,
fixed : false
}
}
);
//this.id = this.id || line.id;
construction.points.push(labelPoint);
construction['labelOf' + this.name] = labelPoint;
construction.lines.push(line);
if (typeof labelPoint.label.content !== 'undefined') {
labelPoint.label.content.setText(this.name);
}
line.on('up', function(event){
var line = this;
var updoptions = {name: geoline.name, geoid: [geoline.p1, geoline.p2]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
//line.point1.triggerEventHandlers('up');
//line.point2.triggerEventHandlers('up');
});
line.on('down', function(event){
var line = this;
var options = {name: geoline.name, geoid: geoline.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoLine.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Line':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoLine.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
},
{
type: 'Select',
label: 'Line type',
key: 'lineType',
value: this.lineType,
data: [
{id: 'line', name: 'Line'},
{id: 'lineSegment', name: 'Line segment'},
{id: 'startingLine', name: 'Starting line segment'},
{id: 'endingLine', name: 'Ending line segment'}
]
}
],
advanced: [
{
type: 'Checkbox',
label: 'Arrow at start',
key: 'firstArrow',
value: this.firstArrow
},
{
type: 'Checkbox',
label: 'Arrow at end',
key: 'lastArrow',
value: this.lastArrow
},
{
type: 'Text',
label: 'Stroke width',
key: 'strokeWidth',
value: this.numToStr(this.strokeWidth)
},
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Line is drawable.
*/
GeoLine.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoLine
{ // GeoCircle
/**
* Constructor for geometric circle object.
*/
var GeoCircle = function(params, geoparent) {
this.type = 'Circle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoCircle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoCircle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || '',
'p2' : this.p2 || '',
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.visible) !== 'undefined' ? this.visible : true),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor': this.fillColor || 'none'
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
// Fallback for the older versions.
if (typeof params.color !== 'undefined'){
this.strokeColor = params.color;
}
}
/**
* Get data of GeoCircle
**/
GeoCircle.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
dash: this.dash,
showName: this.showName,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
radius: this.radius,
area: this.area,
circumference: this.circumference
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoCircle.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoCircle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>c</i>(<i>'+this.getObjName(this.p1)+'</i>; '+this.radius+')</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoCircle.prototype.iconCSS = 'circleBtn';
GeoCircle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-circle"><circle style="stroke: blue; fill: none;" cx="10" cy="10" r="9" /><circle style="stroke: none; fill: red;" cx="10" cy="10" r="2" /><circle style="stroke: none; fill: red;" cx="17" cy="15" r="2" /></svg>';
/**
* Draw the circle on board in the construction.
**/
GeoCircle.prototype.asConstruct = function(board, construction) {
var geocircle = this;
var circle = board.create(
'circle',
[board.objects[this.p1], board.objects[this.p2]],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
dash : this.dash,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor: this.fillColor,
}
);
//this.id = this.id || circle.id;
construction.circles.push(circle);
this.radius = Math.round(circle.midpoint.Dist(circle.point2) * 10) /10;
circle.on('up', function(event){
var circle = this;
var updoptions = {name: geocircle.name, geoid: [geocircle.p1, geocircle.p2]};
$(circle.board.containerObj).trigger('objectupdate', [updoptions]);
});
circle.on('down', function(event){
var circle = this;
var options = {name: geocircle.name, geoid: geocircle.geoid};
$(circle.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoCircle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Circle':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoCircle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Center point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Arc point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Circle is drawable.
*/
GeoCircle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoCircle
{ // GeoRcircle
/**
* Constructor for geometric circle object.
*/
var GeoRcircle = function(params, geoparent) {
this.type = 'Rcircle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoRcircle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoRcircle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3' : this.p3 || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.visible) !== 'undefined' ? this.visible : true),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor': this.fillColor || 'none'
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
}
/**
* Get data of GeoRcircle
**/
GeoRcircle.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3: this.p3,
dash: this.dash,
showName: this.showName,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
radius: this.radius,
area: this.area,
circumference: this.circumference
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoRcircle.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3];
}
/**
* Get list string (to be shown in the object list)
**/
GeoRcircle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>c</i>(<i>'+this.getObjName(this.p1)+'</i>; '+this.radius+')</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRcircle.prototype.iconCSS = 'rcircleBtn';
GeoRcircle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-rcircle"><circle style="stroke: blue; fill: none;" cx="10" cy="10" r="9" /><path style="stroke: red; stroke-width: 2px; fill: none;" d="M10 10 l8 4" /><circle style="stroke: none; fill: black;" cx="10" cy="10" r="2" /></svg>';
/**
* Draw the circle on board in the construction.
**/
GeoRcircle.prototype.asConstruct = function(board, construction) {
var geocircle = this;
var p2 = board.objects[this.p2];
var p3 = board.objects[this.p3];
var circle = board.create(
'circle',
[board.objects[this.p1], function(){return p2.Dist(p3);}],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
dash : this.dash,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor: this.fillColor,
}
);
//this.id = this.id || circle.id;
construction.circles.push(circle);
this.radius = Math.round(p2.Dist(p3) * 10) /10;
circle.on('up', function(event){
var circle = this;
var updoptions = {name: geocircle.name, geoid: [geocircle.p1]};
$(circle.board.containerObj).trigger('objectupdate', [updoptions]);
});
circle.on('down', function(event){
var circle = this;
var options = {name: geocircle.name, geoid: geocircle.geoid};
$(circle.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoRcircle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Rcircle':
case 'Circle':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoRcircle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Center point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Radius start',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Select',
label: 'Radius end',
key: 'p3',
value: this.p3,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Circle is drawable.
*/
GeoRcircle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoRcircle
{ // GeoGlider
/**
* Constructor glider point object on previous element.
*/
var GeoGlider = function(params, geoparent) {
this.type = 'Glider';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoGlider.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoGlider.prototype.setData = function(params){
params = $.extend( {
'parent' : this.parent || null,
'x' : this.x || null,
'y' : this.y || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof (this.visible) !== 'undefined' ? this.visible : true),
'fixed' : this.fixed || false,
'size' : (typeof this.size !== 'undefined' ? this.size : 3),
'color' : this.color || '#ff0000',
'decimalperiod' : this.decimalperiod || false
}, params);
this.size = this.strToNum(params.size);
this.parent = params.parent;
this.x = (params.x == 'null' ? 0 : this.strToNum(params.x));
this.y = (params.y == 'null' ? 0 : this.strToNum(params.y));
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
this.decimalperiod = params.decimalperiod;
}
/**
* Get data of GeoGlider
**/
GeoGlider.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
parent: this.parent,
x: this.x,
y: this.y,
showName: this.showName,
visible: this.visible,
fixed: this.fixed,
size: this.size,
color: this.color
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoGlider.prototype.getDeps = function(){
return [this.parent];
}
/**
* CSS style defining the icon representing this type.
**/
GeoGlider.prototype.iconCSS = 'gliderBtn';
GeoGlider.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-glider"><line style="stroke: blue;" x1="0" y1="7" x2="20" y2="13" /><circle style="stroke: #f00; fill: #fff;" cx="10" cy="10" r="2" /></svg>';
/**
* Draw the glider on board in the construction.
*/
GeoGlider.prototype.asConstruct = function(board, construction) {
var geopoint = this;
var obj = this;
if ((this.x != null) && (this.y != null)) {
var p = board.create(
'glider',
[this.strToNum(this.x), this.strToNum(this.y), board.objects[this.parent]],
{
name : this.name,
id : this.geoid,
size : this.size,
//color: (this.fixed ? '#000000' : this.color),
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
strokeColor: this.color,
fillColor: 'white'
}
);
} else {
var p = board.create(
'glider',
[board.objects[this.parent]],
{
name : this.name,
id : this.geoid,
size : this.size,
//color: (this.fixed ? '#000000' : this.color),
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
strokeColor: this.color,
fillColor: 'white'
}
);
}
if (!this.name) {
this.name = p.name;
}
//this.id = this.id || p.id;
p.obj = obj;
construction.points.push(p);
construction[this.name] = p;
if (this.showName){
p.label.content.setText(this.nameStr(construction));
}
p.on('up', function(event){
var point = this;
var options = {name: geopoint.name, id: geopoint.geoid};
$(point.board.containerObj).trigger('objectupdate', [options]);
});
p.on('down', function(event){
var point = this;
var options = {name: geopoint.name, geoid: geopoint.geoid};
$(point.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Update data of the object from the board.
**/
GeoGlider.prototype.updateFromBoard = function(board){
var point = board.objects[this.geoid];
this.x = Math.round(point.X() * 100)/100;
this.y = Math.round(point.Y() * 100)/100;
}
/**
* Get list of elements of given type.
**/
GeoGlider.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Glider':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
*/
GeoGlider.prototype.getOptionsDialog = function() {
var curvelist = this.geoparent.getCurves();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Parent',
key: 'parent',
value: this.parent,
data: curvelist
},
{
type: 'Text',
label: 'x-coordinate',
key: 'x',
value: (typeof(this.x) === 'number' ? this.numToStr(this.x) : '')
},
{
type: 'Text',
label: 'y-coordinate',
key: 'y',
value: (typeof(this.y) === 'number' ? this.numToStr(this.y) : '')
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Fixed',
key: 'fixed',
value: this.fixed
},
{
type: 'Text',
label: 'Size',
key: 'size',
value: this.numToStr(this.size)
}
]
}
return dialog;
}
/**
* Tell, if Glider is drawable.
*/
GeoGlider.prototype.drawable = function(board){
return !!board.objects[this.parent];
}
} // End GeoGlider
{ // GeoMidpoint
/**
* Constructor Midpoint object on previous element.
*/
var GeoMidpoint = function(params, geoparent) {
this.type = 'Midpoint';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoMidpoint.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoMidpoint.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof (this.visible) !== 'undefined' ? this.visible : true),
'fixed' : this.fixed || false,
'size' : (typeof this.size !== 'undefined' ? this.size : 3),
'color' : this.color || '#ff0000',
'decimalperiod' : this.decimalperiod || false
}, params);
this.size = this.strToNum(params.size);
this.p1 = params.p1;
this.p2 = params.p2;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
this.decimalperiod = params.decimalperiod;
}
/**
* Get data of GeoMidpoint
**/
GeoMidpoint.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
showName: this.showName,
visible: this.visible,
fixed: this.fixed,
size: this.size,
color: this.color
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoMidpoint.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* CSS style defining the icon representing this type.
**/
GeoMidpoint.prototype.iconCSS = 'midpointBtn';
GeoMidpoint.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-midpoint"><line style="stroke: blue;" x1="0" y1="7" x2="20" y2="13" /><circle style="stroke: none; fill: #000;" cx="3" cy="7.7" r="2" /><circle style="stroke: none; fill: #f00;" cx="10" cy="10" r="2" /><circle style="stroke: none; fill: #000;" cx="17" cy="12.3" r="2" /></svg>';
/**
* Draw the glider on board in the construction.
*/
GeoMidpoint.prototype.asConstruct = function(board, construction) {
var geopoint = this;
var obj = this;
var p = board.create(
'midpoint',
[this.p1, this.p2],
{
name : this.name,
id : this.geoid,
size : this.size,
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
face : '<>',
strokeColor: this.color,
fillColor: this.color
}
);
if (!this.name) {
this.name = p.name;
}
p.obj = obj;
construction.points.push(p);
construction[this.name] = p;
if (this.showName){
p.label.content.setText(this.nameStr(construction));
}
p.on('down', function(event){
var point = this;
var options = {name: geopoint.name, geoid: geopoint.geoid};
$(point.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoMidpoint.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Midpoint':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
*/
GeoMidpoint.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Point 1',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Point 2',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Fixed',
key: 'fixed',
value: this.fixed
},
{
type: 'Text',
label: 'Size',
key: 'size',
value: this.numToStr(this.size)
}
]
}
return dialog;
}
/**
* Tell, if Midpoint is drawable.
*/
GeoMidpoint.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoMidpoint
{ // GeoIntersection
/**
* Constructor intersection points on two previous elements.
*/
var GeoIntersection = function(params, geoparent) {
this.type = 'Intersection';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoIntersection.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoIntersection.prototype.setData = function(params){
params = $.extend( {
'parent1' : (typeof(this.parent1) !== 'undefined' ? this.parent1 : null),
'parent2' : (typeof(this.parent2) !== 'undefined' ? this.parent2 : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.visible) !== 'undefined' ? this.visible : true),
'fixed' : this.fixed || false,
'size' : (typeof this.size !== 'undefined' ? this.size : 6),
'color' : this.color || '#ff0000',
'showPoints' : this.showPoints || 'both',
'decimalperiod' : this.decimalperiod || false
}, params);
this.size = this.strToNum(params.size);
this.parent1 = params.parent1 || this.parent1;
this.parent2 = params.parent2 || this.parent2;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
this.showPoints = params.showPoints;
this.decimalperiod = params.decimalperiod;
}
/**
* Get data of GeoIntersection
**/
GeoIntersection.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
parent1: this.parent1,
parent2: this.parent2,
showName: this.showName,
visible: this.visible,
fixed: this.fixed,
size: this.size,
color: this.color,
showPoints: this.showPoints
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoIntersection.prototype.getDeps = function(){
return [this.parent1, this.parent2];
}
/**
* CSS style defining the icon representing this type.
**/
GeoIntersection.prototype.iconCSS = 'intersectionBtn';
GeoIntersection.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-intersection"><line style="stroke: blue;" x1="0" y1="7" x2="20" y2="13" /><line style="stroke: blue;" x1="18" y1="0" x2="3" y2="20" /><circle style="stroke: #a00; fill: #f00;" cx="10" cy="10" r="2" /></svg>';
/**
* Draw the intersections on board in the construction.
*/
GeoIntersection.prototype.asConstruct = function(board, construction) {
var geopoint = this;
var obj = this;
this.doubleintersection = (
board.objects[this.parent1].elType === 'circle' ||
board.objects[this.parent2].elType === 'circle');
if ((this.parent1 != null) && (this.parent2 != null)) {
if (this.showPoints === 'both' || this.showPoints === 'first') {
var p1 = board.create(
'intersection',
[this.parent1, this.parent2, 0],
{
name : this.name + '_1',
id : this.geoid + '_1',
size : this.size,
color: (this.fixed ? '#000000' : this.color),
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
face: '+',
strokeColor: this.color,
fillColor: this.color
}
);
construction.intersections.push(p1);
construction[this.name + '_1'] = p1;
if (this.showName){
p1.label.content.setText(this.nameStr() + (this.doubleintersection ? '_1' : ''));
}
p1.on('down', function(event){
var point = this;
var options = {name: geopoint.name, geoid: geopoint.geoid};
$(point.board.containerObj).trigger('objectselected', [options]);
});
}
if (this.doubleintersection && (this.showPoints === 'both' || this.showPoints === 'second')) {
var p2 = board.create(
'intersection',
[this.parent1, this.parent2, 1],
{
name : this.name + '_2',
id : this.geoid + '_2',
size : this.size,
color: (this.fixed ? '#000000' : this.color),
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
face: '+',
strokeColor: this.color,
fillColor: this.color
}
);
construction.intersections.push(p2);
construction[this.name + '_2'] = p2;
if (this.showName){
p1 && p1.label.content.setText(this.nameStr() + '_1');
p2 && p2.label.content.setText(this.nameStr() + '_2');
}
p2.on('down', function(event){
var point = this;
var options = {name: geopoint.name, geoid: geopoint.geoid};
$(point.board.containerObj).trigger('objectselected', [options]);
});
}
}
}
/**
* Update data of the object from the board.
**/
GeoIntersection.prototype.updateFromBoard = function(board){}
/**
* Select this object.
**/
GeoIntersection.prototype.select = function(board){
board.objects[this.geoid + '_1'] && board.objects[this.geoid + '_1'].setProperty({shadow: true});
board.objects[this.geoid + '_2'] && board.objects[this.geoid + '_2'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoIntersection.prototype.deselect = function(board){
board.objects[this.geoid + '_1'] && board.objects[this.geoid + '_1'].setProperty({shadow: false});
board.objects[this.geoid + '_2'] && board.objects[this.geoid + '_2'].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoIntersection.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Point':
case 'Intersection':
list.push({id: this.geoid + '_1', name: this.name + (this.doubleintersection ? '_1': '')});
if (this.doubleintersection) {
list.push({id: this.geoid + '_2', name: this.name + '_2'});
}
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
*/
GeoIntersection.prototype.getOptionsDialog = function() {
var curvelist = this.geoparent.getCurves();
var showpoints = [
{
id: 'both',
name: 'both'
},
{
id: 'first',
name: 'first'
},
{
id: 'second',
name: 'second'
}
]
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Parent 1',
key: 'parent1',
value: this.parent1,
data: curvelist
},
{
type: 'Select',
label: 'Parent 2',
key: 'parent2',
value: this.parent2,
data: curvelist
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Fixed',
key: 'fixed',
value: this.fixed
},
{
type: 'Text',
label: 'Size',
key: 'size',
value: this.numToStr(this.size)
},
{
type: 'Select',
label: 'Show points',
key: 'showPoints',
value: this.showPoints,
data: showpoints
}
]
}
return dialog;
}
/**
* Tell, if Intersection is drawable.
*/
GeoIntersection.prototype.drawable = function(board){
return !!board.objects[this.parent1] && !!board.objects[this.parent2];
}
} // End GeoIntersection
{ // GeoTriangle
/**
* Constructor for geometric triangle object.
*/
var GeoTriangle = function(params, geoparent) {
this.type = 'Triangle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoTriangle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoTriangle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3' : this.p3 || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor' : this.fillColor || 'none',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.lang = params.lang;
}
/**
* Get data of GeoTriangle
**/
GeoTriangle.prototype.getData = function(subid){
if (!subid) {
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3: this.p3,
dash: this.dash,
showName: this.showName,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
labelOffset: this.labelOffset
}
} else {
var data = {};
switch (subid){
case 'side1':
data.type = 'Line';
data.geoid = this.geoid + '-side1';
data.p1 = this.p1;
data.p2 = this.p2;
break;
case 'side2':
data.type = 'Line';
data.geoid = this.geoid + '-side2';
data.p1 = this.p2;
data.p2 = this.p3;
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side3';
data.p1 = this.p3;
data.p2 = this.p1;
break;
default:
break
}
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoTriangle.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3];
}
/**
* Get list string (to be shown in the object list)
**/
GeoTriangle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u25b3'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.getObjName(this.p3)+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoTriangle.prototype.iconCSS = 'triangleBtn';
GeoTriangle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-triangle"><path style="stroke: blue; fill: none;" d="M4 4 l12 10 l-13 2z" /><circle style="stroke: none; fill: red;" cx="4" cy="4" r="2" /><circle style="stroke: none; fill: red;" cx="16" cy="14" r="2" /><circle style="stroke: none; fill: red;" cx="3" cy="16" r="2" /></svg>';
/**
* Draw the triangle on board in the construction.
**/
GeoTriangle.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var line1 = board.create(
'line',
[board.objects[this.p1], board.objects[this.p2]],
{
visible : this.visible,
name : '',
id : this.geoid + '-side1',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line1);
var line2 = board.create(
'line',
[board.objects[this.p2], board.objects[this.p3]],
{
visible : this.visible,
name : '',
id : this.geoid + '-side2',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line2);
var line3 = board.create(
'line',
[board.objects[this.p1], board.objects[this.p3]],
{
visible : this.visible,
name : '',
id : this.geoid + '-side3',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line3);
var polygon = board.create(
'polygon',
[board.objects[this.p1], board.objects[this.p2], board.objects[this.p3]],
{
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
);
construction.polygons.push(polygon);
line1.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p2]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line2.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p2, geoobject.p3]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line3.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p3]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line3.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoTriangle.prototype.select = function(board){
board.objects[this.geoid + '-side1'].setProperty({shadow: true});
board.objects[this.geoid + '-side2'].setProperty({shadow: true});
board.objects[this.geoid + '-side3'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoTriangle.prototype.deselect = function(board){
board.objects[this.geoid + '-side1'].setProperty({shadow: false});
board.objects[this.geoid + '-side2'].setProperty({shadow: false});
board.objects[this.geoid + '-side3'].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoTriangle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Triangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Linelike':
list.push({id: this.geoid + '-side1', name: this.name + '_1'});
list.push({id: this.geoid + '-side2', name: this.name + '_2'});
list.push({id: this.geoid + '-side3', name: this.name + '_3'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoTriangle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Select',
label: 'Third point',
key: 'p3',
value: this.p3,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Triangle is drawable.
*/
GeoTriangle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2] && !!board.objects[this.p3];
}
} // End GeoTriangle
{ // GeoRighttriangle
/**
* Constructor for geometric right triangle object.
*/
var GeoRighttriangle = function(params, geoparent) {
this.type = 'Righttriangle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoRighttriangle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoRighttriangle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3x' : (typeof(this.p3x) !== 'undefined' ? this.p3x : null),
'p3y' : (typeof(this.p3y) !== 'undefined' ? this.p3y : null),
'p3name' : (typeof(this.p3name) !== 'undefined' ? this.p3name : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'showGeneratedPoints' : (typeof this.showGeneratedPoints !== 'undefined' ? this.showGeneratedPoints : true),
'showGeneratedName' : (typeof this.showGeneratedName !== 'undefined' ? this.showGeneratedName : true),
'showRightangle' : (typeof this.showRightangle !== 'undefined' ? this.showRightangle : false),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor' : this.fillColor || 'none',
'strokeWidth' : 2
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3geoid = this.geoid + '-p3';
this.p3x = params.x || params.p3x;
this.p3y = params.y || params.p3y;
this.p3name = params.p3name;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.showGeneratedPoints = params.showGeneratedPoints;
this.showGeneratedName = params.showGeneratedName;
this.showRightangle = params.showRightangle;
this.visible = params.visible;
this.strokeColor = params.strokeColor || params.color;
this.fillColor = params.fillColor;
this.angleradius = 0.5;
}
/**
* Get data of GeoRighttriangle
**/
GeoRighttriangle.prototype.getData = function(subid){
if (!subid) {
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3x: this.p3x,
p3y: this.p3y,
p3name: this.p3name,
dash: this.dash,
showName: this.showName,
showGeneratedPoints: this.showGeneratedPoints,
showGeneratedName: this.showGeneratedName,
showRightangle: this.showRightangle,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor
}
} else {
var data = {};
switch (subid){
case 'side1':
data.type = 'Line';
data.geoid = this.geoid + '-side1';
data.p1 = this.p1;
data.p2 = this.p2;
break;
case 'side2':
data.type = 'Line';
data.geoid = this.geoid + '-side2';
data.p1 = this.p2;
data.p2 = this.geoid + '-p3';
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side3';
data.p1 = this.geoid + '-p3';
data.p2 = this.p1;
break;
default:
break
}
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoRighttriangle.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoRighttriangle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u25b3'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.getObjName(this.p3)+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRighttriangle.prototype.iconCSS = 'righttriangleBtn';
GeoRighttriangle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-righttriangle"><path stroke="red" fill="none" d="M16 12 l-5 0 l0 5 l5 0z" /><path style="stroke: blue; fill: none;" d="M16 2 l0 15 l-14 0z" /><circle style="stroke: none; fill: red;" cx="16" cy="2" r="2" /><circle style="stroke: none; fill: red;" cx="3" cy="17" r="2" /><circle style="stroke: red; fill: white;" cx="16" cy="17" r="2" /></svg>';
/**
* Draw the right triangle on board in the construction.
**/
GeoRighttriangle.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var midpoint = board.create(
'midpoint',
[this.p1, this.p2],
{visible: false, id: this.geoid + '-midpoint', name: ''}
);
midpoint.gedithelpobject = true;
var circle = board.create(
'circle',
[this.geoid + '-midpoint', this.p1],
{visible: false, id: this.geoid + '-circle', name: ''}
);
circle.gedithelpobject = true;
this.p3 = board.create(
'glider',
[this.p3x, this.p3y, circle],
{visible: this.showGeneratedPoints, id: this.geoid + '-p3', name: (this.showGeneratedName ? this.p3name: ''), fillColor: 'white'}
);
var line1 = board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : '',
id : this.geoid + '-side1',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line1);
var line2 = board.create(
'line',
[this.p2, this.p3],
{
visible : this.visible,
name : '',
id : this.geoid + '-side2',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line2);
var line3 = board.create(
'line',
[this.p1, this.p3],
{
visible : this.visible,
name : '',
id : this.geoid + '-side3',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line3);
var polygon = board.create(
'polygon',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
);
construction.polygons.push(polygon);
var p1 = board.objects[this.p1];
var p2 = board.objects[this.p2];
if (this.showRightangle) {
board.create(
'angle',
[this.p2, this.p3, this.p1],
{
visible: (JXG.Math.Geometry.trueAngle(p2, this.p3, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle1',
name: function(){
board.objects[geoobject.geoid + '_rangle1'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p2, geoobject.p3, p1).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p1, this.p3, this.p2],
{
visible: (JXG.Math.Geometry.trueAngle(p1, this.p3, p2).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle2',
name: function(){
board.objects[geoobject.geoid + '_rangle2'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, geoobject.p3, p2).toFixed(0) < 180)});
return '';
}
}
);
}
this.p3.on('up', function(event){
var point = this;
var options = {
id: geoobject.geoid,
x: Math.round(point.X() * 100)/100,
y: Math.round(point.Y() * 100)/100,
element: geoobject
};
$(point.board.containerObj).trigger('objectupdate', [options]);
// Or should this be 'objectupdate'?
return false;
});
line1.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p2]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line3.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoRighttriangle.prototype.select = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: true});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: true});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoRighttriangle.prototype.deselect = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: false});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: false});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: false});
}
/**
* Update data of the object from the board.
**/
GeoRighttriangle.prototype.updateFromBoard = function(board){
var point = board.objects[this.geoid + '-p3'];
this.p3x = Math.round(point.X() * 100)/100;
this.p3y = Math.round(point.Y() * 100)/100;
}
/**
* Get list of elements of given type.
**/
GeoRighttriangle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Point':
list.push({id: this.p3geoid, name: this.p3name});
break;
case 'Triangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Righttriangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Linelike':
list.push({id: this.geoid + '-side1', name: this.name + '_1'});
list.push({id: this.geoid + '-side2', name: this.name + '_2'});
list.push({id: this.geoid + '-side3', name: this.name + '_3'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoRighttriangle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Text',
label: 'Third point name',
key: 'p3name',
value: this.p3name
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Show generated point',
key: 'showGeneratedPoints',
value: this.showGeneratedPoints
},
{
type: 'Checkbox',
label: 'Show generated name',
key: 'showGeneratedName',
value: this.showGeneratedName
},
{
type: 'Checkbox',
label: 'Show right angle',
key: 'showRightangle',
value: this.showRightangle
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Right triangle is drawable.
*/
GeoRighttriangle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoRighttriangle
{ // GeoRtriangle
/**
* Constructor for geometric right triangle object.
*/
var GeoRtriangle = function(params, geoparent) {
this.type = 'Rtriangle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoRtriangle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoRtriangle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3dist' : (typeof(this.p3dist) !== 'undefined' ? this.p3dist : null),
'p3name' : (typeof(this.p3name) !== 'undefined' ? this.p3name : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'showP3' : (typeof(this.showP3) !== 'undefined' ? this.showP3 : true),
'showP3Name' : (typeof(this.showP3Name) !== 'undefined' ? this.showP3Name : true),
'showRightangle' : (typeof this.showRightangle !== 'undefined' ? this.showRightangle : false),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor' : this.fillColor || 'none',
'strokeWidth' : 2
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3geoid = this.geoid + '-p3';
this.p3dist = this.getDist(params.p3x, params.p3y, params.p3dist);
this.p3name = params.p3name;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.showP3 = params.showP3;
this.showP3Name = params.showP3Name;
this.showRightangle = params.showRightangle;
this.visible = params.visible;
this.strokeColor = params.strokeColor || params.color;
this.fillColor = params.fillColor;
this.angleradius = 0.5;
}
/**
* Get the distance of p3 from p3 with given coordinates of p3.
* The sign + means right from segment p2 p1 and - means left of it.
* The third argument is returned, if x or y is undefined.
**/
GeoRtriangle.prototype.getDist = function(x, y, defaultval){
var dist = defaultval;
if (typeof(x) !== 'undefined' && typeof(y) !== 'undefined') {
var sign;
if (this.p1x-this.p2x === 0) {
sign = (x > this.p2x ? +1 : -1);
} else if (this.p1x > this.p2x) {
sign = (y > (this.p1y-this.p2y)/(this.p1x-this.p2x)*(x-this.p1x) + this.p1y ? -1 : 1);
} else {
sign = (y > (this.p1y-this.p2y)/(this.p1x-this.p2x)*(x-this.p1x) + this.p1y ? 1 : -1);
}
var dx = this.p2x - x;
var dy = this.p2y - y;
dist = sign * Math.sqrt(dx*dx + dy*dy);
}
return dist;
}
/**
* Get data of GeoRtriangle
**/
GeoRtriangle.prototype.getData = function(subid){
if (!subid) {
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3dist: this.p3dist,
dash: this.dash,
showName: this.showName,
showP3: this.showP3,
showP3Name: this.showP3Name,
showRightangle: this.showRightangle,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
labelOffset: this.labelOffset
}
} else {
var data = {};
switch (subid){
case 'side1':
data.type = 'Line';
data.geoid = this.geoid + '-side1';
data.p1 = this.p1;
data.p2 = this.p2;
break;
case 'side2':
data.type = 'Line';
data.geoid = this.geoid + '-side2';
data.p1 = this.p2;
data.p2 = this.p3;
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side3';
data.p1 = this.p3;
data.p2 = this.p1;
break;
default:
break
}
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoRtriangle.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3geoname];
}
/**
* Get list string (to be shown in the object list)
**/
GeoRtriangle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u25b3'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.getObjName(this.p3)+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRtriangle.prototype.iconCSS = 'rtriangleBtn';
GeoRtriangle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-rtriangle"><path stroke="red" fill="none" d="M8 12 l-5 0 l0 5 l5 0z" /><path style="stroke: blue; fill: none;" d="M3 2 l0 15 l15 0z" /><circle style="stroke: none; fill: red;" cx="3" cy="2" r="2" /><circle style="stroke: none; fill: red;" cx="3" cy="17" r="2" /><circle style="stroke: red; fill: white;" cx="18" cy="17" r="2" /></svg>';
/**
* Draw the right triangle on board in the construction.
**/
GeoRtriangle.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var p1 = board.objects[this.p1];
var p2 = board.objects[this.p2];
this.p1x = p1.X();
this.p1y = p1.Y();
this.p2x = p2.X();
this.p2y = p2.Y();
var line1 = board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : '',
id : this.geoid + '-side1',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line1);
var normal1 = board.create(
'normal',
[this.p2, line1],
{
visible : false,
name : '',
id : this.geoid + '-normal1'
}
);
normal1.gedithelpobject = true;
var dx = p2.X() - p1.X();
var dy = p2.Y() - p1.Y();
var hypot = Math.sqrt(dx*dx + dy*dy);
var ratio = this.p3dist/hypot;
var p3x = p2.X() - dy*ratio;
var p3y = p2.Y() + dx*ratio;
this.p3 = board.create(
'glider',
[p3x, p3y, normal1],
{
visible: this.showP3,
name: (this.showP3Name ? this.p3name : ''),
id: this.p3geoid,
strokeColor: 'red',
fillColor: 'white'
}
);
var line2 = board.create(
'line',
[this.p2, this.p3],
{
visible : this.visible,
name : '',
id : this.geoid + '-side2',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line2);
var line3 = board.create(
'line',
[this.p3, this.p1],
{
visible : this.visible,
name : '',
id : this.geoid + '-side3',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line3);
var polygon = board.create(
'polygon',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
);
construction.polygons.push(polygon);
if (this.showRightangle) {
board.create(
'angle',
[this.p1, this.p2, this.p3],
{
visible: (JXG.Math.Geometry.trueAngle(p1, p2, this.p3).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle1',
name: function(){
board.objects[geoobject.geoid + '_rangle1'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, p2, geoobject.p3).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p3, this.p2, this.p1],
{
visible: (JXG.Math.Geometry.trueAngle(this.p3, p2, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle2',
name: function(){
board.objects[geoobject.geoid + '_rangle2'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geoobject.p3, p2, p1).toFixed(0) < 180)});
return '';
}
}
);
}
this.p3.on('up', function(event){
var point = this;
var p3x = point.X();
var p3y = point.Y();
geoobject.setData({p3x: p3x, p3y: p3y});
$(point.board.containerObj).trigger('objectupdate', [{name: geoobject.name, geoid: []}]);
});
line1.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p2, geoobject.geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line2.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p2, geoobject.p3geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line3.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p3geoid, geoobject.p4geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line3.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoRtriangle.prototype.select = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: true});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: true});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoRtriangle.prototype.deselect = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: false});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: false});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: false});
}
/**
* Update data of the object from the board.
**/
GeoRtriangle.prototype.updateFromBoard = function(board){
var p1 = board.objects[this.p1];
var p2 = board.objects[this.p2];
this.p1x = p1.X();
this.p1y = p1.Y();
this.p2x = p2.X();
this.p2y = p2.Y();
var p3 = board.objects[this.p3geoid];
this.p3dist = this.getDist(p3.X(), p3.Y(), this.p3dist);
}
/**
* Get list of elements of given type.
**/
GeoRtriangle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Point':
list.push({id: this.p3geoid, name: this.p3name});
break;
case 'Triangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Rtriangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Linelike':
list.push({id: this.geoid + '-side1', name: this.name + '_1'});
list.push({id: this.geoid + '-side2', name: this.name + '_2'});
list.push({id: this.geoid + '-side3', name: this.name + '_3'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoRtriangle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Text',
label: 'Third point name',
key: 'p3name',
value: this.p3name
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Show third point',
key: 'showP3',
value: this.showP3
},
{
type: 'Checkbox',
label: 'Show third point name',
key: 'showP3Name',
value: this.showP3Name
},
{
type: 'Checkbox',
label: 'Show right angle',
key: 'showRightangle',
value: this.showRightangle
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Right triangle is drawable.
*/
GeoRtriangle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoRighttriangle2
{ // GeoAngle
/**
* Constructor for geometric Angle object.
*/
var GeoAngle = function(params, geoparent) {
this.type = 'Angle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoAngle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoAngle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3' : this.p3 || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'mode' : this.mode || 'angle',
'strokeColor' : this.strokeColor || '#ff0000',
'fillColor' : this.fillColor || '#ff0000',
'radius' : (typeof this.radius !== 'undefined' ? this.radius : 1.0),
'fillOpacity' : (typeof this.fillOpacity !== 'undefined' ? this.fillOpacity : 0.3),
'label' : {
'fixed': false
}
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.showName = params.showName;
this.fillOpacity = params.fillOpacity;
this.visible = params.visible;
this.mode = params.mode;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.radius = this.strToNum(params.radius);
}
/**
* Get data of GeoAngle
**/
GeoAngle.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3: this.p3,
mode: this.mode,
showName: this.showName,
visible: this.visible,
fillOpacity: this.fillOpacity,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
radius: this.radius
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoAngle.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3];
}
/**
* Get list string (to be shown in the object list)
**/
GeoAngle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u2220'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.getObjName(this.p3)+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoAngle.prototype.iconCSS = 'angleBtn';
GeoAngle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-angle"><path style="stroke: #ff0000; fill: rgba(255,0,0,0.2);" d="M3 16 l10 -2 a11 11 0 0 0 -6 -7z" /><circle style="stroke: none; fill: red;" cx="11" cy="2" r="1.5" /><circle style="stroke: none; fill: red;" cx="18" cy="12" r="1.5" /><circle style="stroke: none; fill: red;" cx="3" cy="16" r="1.5" /><circle style="stroke: none; fill: blue;" cx="13" cy="8" r="1" /></svg>';
/**
* Return the value of angle (as degrees).
**/
GeoAngle.prototype.val = function() {
var p1 = this.geoparent.board.objects[this.p1];
var p2 = this.geoparent.board.objects[this.p2];
var p3 = this.geoparent.board.objects[this.p3];
var angval = JXG.Math.Geometry.trueAngle(p1, p2, p3).toFixed(0);
return angval;
}
/**
* Return the value of angle (as degrees).
**/
GeoAngle.prototype.angleVal = function() {
var angval = this.val();
if ((this.mode === 'angleSmall' && angval > 180) ||
(this.mode === 'angleLarge' && angval <= 180)) {
angval = 360 - angval;
}
return angval;
}
/**
* Return the value of angle as a string.
**/
GeoAngle.prototype.angleStr = function() {
if (this.showName) {
var angle = this.angleVal() + '°';
if (this.name === '') {
var angleValue = this.val();
if ((angleValue === 90) || ((angleValue === 270) && (this.mode == 'angleSmall'))){
return ' ';
} else {
return angle;
}
} else {
return this.name.replace(/%1/g, angle);
}
} else {
return '';
}
}
/**
* Draw the angle on board in the construction.
**/
GeoAngle.prototype.asConstruct = function(board, construction) {
var geoobject = this;
if (!construction.angle) {
construction.angle = [];
}
if (this.mode === 'angle') {
var angle1 = board.create(
'angle',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
id : this.geoid + '_1',
withLabel : true,
strokeWidth : 2,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
fillOpacity : this.fillOpacity,
radius : this.radius,
needsRegularUpdate : true,
orthoSensitivity : 0.5,
label : {strokeColor: 'black'},
point : {visible: false},
name : function(){
return geoobject.angleStr();
}
}
);
construction.angle.push(angle1);
}
if (this.mode === 'angleSmall' || this.mode === 'angleLarge') {
var angle1 = board.create(
'angle',
[this.p1, this.p2, this.p3],
{
visible : geoobject.visible &&
((geoobject.mode === 'angleSmall' && geoobject.val() <= 180) ||
(geoobject.mode === 'angleLarge' && geoobject.val() > 180)),
id : this.geoid + '_1',
withLabel : true,
strokeWidth : 2,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
fillOpacity : this.fillOpacity,
radius : this.radius,
needsRegularUpdate : true,
orthoSensitivity : 0.5,
label : {strokeColor: 'black'},
point : {visible: false},
name : function(){
board.objects[geoobject.geoid+'_1'].setProperty({
visible: (geoobject.visible &&
((geoobject.mode === 'angleSmall' && geoobject.val() <= 180) ||
(geoobject.mode === 'angleLarge' && geoobject.val() > 180)))
});
return geoobject.angleStr();
}
}
);
construction.angle.push(angle1);
var angle2 = board.create(
'angle',
[this.p3, this.p2, this.p1],
{
visible : this.visible &&
((this.mode === 'angleSmall' && geoobject.val() > 180) ||
(geoobject.mode === 'angleLarge' && geoobject.val() <= 180)),
id : this.geoid + '_2',
withLabel : true,
strokeWidth : 2,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
fillOpacity : this.fillOpacity,
radius : this.radius,
needsRegularUpdate : true,
orthoSensitivity : 0.5,
label : {strokeColor: 'black'},
point : {visible: false},
name : function(){
board.objects[geoobject.geoid+'_2'].setProperty({
visible: (geoobject.visible &&
((geoobject.mode === 'angleSmall' && geoobject.val() > 180) ||
(geoobject.mode === 'angleLarge' && geoobject.val() <= 180)))
});
return geoobject.angleStr();
}
}
);
construction.angle.push(angle1);
angle2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
angle1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoAngle.prototype.select = function(board){
board.objects[this.geoid + '_1'] && board.objects[this.geoid + '_1'].setProperty({shadow: true});
board.objects[this.geoid + '_2'] && board.objects[this.geoid + '_2'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoAngle.prototype.deselect = function(board){
board.objects[this.geoid + '_1'] && board.objects[this.geoid + '_1'].setProperty({shadow: false});
board.objects[this.geoid + '_2'] && board.objects[this.geoid + '_2'].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoAngle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Angle':
list.push({id: this.geoid+'_1', name: this.name});
list.push({id: this.geoid+'_2', name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoAngle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Right point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Corner point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Select',
label: 'Left point',
key: 'p3',
value: this.p3,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Text',
label: 'Radius',
key: 'radius',
value: this.radius
},
{
type: 'Text',
label: 'Fill opacity',
key: 'fillOpacity',
value: this.fillOpacity
},
{
type: 'Select',
label: 'Angle mode',
key: 'mode',
value: this.mode,
data: [
{id: 'angle', name: 'Angle'},
{id: 'angleSmall', name: 'Small angle'},
{id: 'angleLarge', name: 'Large angle'}
]
}
]
}
return dialog;
}
/**
* Tell, if Angle is drawable.
*/
GeoAngle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2] && !!board.objects[this.p3];
}
} // End GeoAngle
{ // GeoBisector
/**
* Constructor for geometric Bisector object.
*/
var GeoBisector = function(params, geoparent) {
this.type = 'Bisector';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoBisector.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoBisector.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3' : this.p3 || null,
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'strokeColor' : this.strokeColor || '#0000ff',
'dash' : (typeof this.dash !== 'undefined' ? this.dash : 0),
'isray' : (typeof this.isray !== 'undefined' ? this.isray : true)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.dash = params.dash;
this.isray = params.isray;
}
/**
* Get data of GeoBisector
**/
GeoBisector.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3: this.p3,
showName: this.showName,
visible: this.visible,
strokeColor: this.strokeColor,
dash: this.dash,
isray: this.isray
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoBisector.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3];
}
/**
* Get list string (to be shown in the object list)
**/
GeoBisector.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka"></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoBisector.prototype.iconCSS = 'bisectorBtn';
GeoBisector.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-bisector"><line style="stroke: black;" x1="3" y1="16" x2="11" y2="2" /><line style="stroke: black;" x1="3" y1="16" x2="18" y2="12" /><line style="stroke: blue;" x1="0" y1="19" x2="20" y2="2" /><circle style="stroke: none; fill: red;" cx="11" cy="2" r="1.5" /><circle style="stroke: none; fill: red;" cx="18" cy="12" r="1.5" /><circle style="stroke: none; fill: red;" cx="3" cy="16" r="1.5" /></svg>';
/**
* Draw the bisector on board in the construction.
**/
GeoBisector.prototype.asConstruct = function(board, construction) {
var geoobject = this;
if (!construction.bisector) {
construction.bisector = [];
}
var bisect = board.create(
'bisector',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
id : this.geoid,
withLabel : true,
strokeWidth : 2,
strokeColor : this.strokeColor,
straightFirst : !this.isray,
dash: this.dash,
name : this.name
}
);
construction.bisector.push(bisect);
bisect.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoBisector.prototype.select = function(board){
board.objects[this.geoid] && board.objects[this.geoid].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoBisector.prototype.deselect = function(board){
board.objects[this.geoid] && board.objects[this.geoid].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoBisector.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Bisector':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoBisector.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Right point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Corner point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Select',
label: 'Left point',
key: 'p3',
value: this.p3,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Is ray',
key: 'isray',
value: this.isray
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Bisector is drawable.
*/
GeoBisector.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2] && !!board.objects[this.p3];
}
} // End GeoBisector
{ // GeoNormal
/**
* Constructor for geometric normal object.
*/
var GeoNormal = function(params, geoparent) {
this.type = 'Normal';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoNormal.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoNormal.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'name' : (typeof this.name !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'color' : this.color || '#0000ff',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name || this.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
}
/**
* Get data of GeoNormal
**/
GeoNormal.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
dash: this.dash,
showName: this.showName,
visible: this.visible,
color: this.color,
strokeWidth: this.strokeWidth
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoNormal.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoNormal.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u27c2</i>(<i>'+this.getObjName(this.p1)+'</i>,<i>'+this.getObjName(this.p2)+'</i>)</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoNormal.prototype.iconCSS = 'normalBtn';
GeoNormal.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-normal"><line style="stroke: blue;" x1="0" y1="4" x2="20" y2="17" /><line style="stroke: black;" x1="20" y1="4" x2="8" y2="20" /><circle style="stroke: none; fill: red;" cx="4.5" cy="7" r="2" /></svg>';
/**
* Draw the normal on board in the construction.
**/
GeoNormal.prototype.asConstruct = function(board, construction) {
var geonormal = this;
var normal = board.create(
'normal',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
straightFirst : true,
straightLast : true,
dash : this.dash,
strokeWidth : this.strokeWidth,
color : this.color
}
);
construction.lines.push(normal);
normal.on('up', function(event){
var line = this;
var updoptions = {name: geonormal.name, geoid: [geonormal.p1, geonormal.p2]};
$(normal.board.containerObj).trigger('objectupdate', [updoptions]);
});
normal.on('down', function(event){
var normal = this;
var options = {name: geonormal.name, geoid: geonormal.geoid};
$(normal.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoNormal.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Linelike':
list.push({id: this.geoid, name: this.name});
break;
case 'Normal':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoNormal.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var curvelist = this.geoparent.getCurves();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Curve',
key: 'p1',
value: this.p1,
data: curvelist
},
{
type: 'Select',
label: 'Point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
},
{
type: 'Select',
label: 'Line type',
key: 'lineType',
value: this.lineType,
data: [
{id: 'line', name: 'Line'},
{id: 'lineSegment', name: 'Line segment'},
{id: 'startingLine', name: 'Starting line segment'},
{id: 'endingLine', name: 'Ending line segment'}
]
}
],
advanced: [
{
type: 'Text',
label: 'Stroke width',
key: 'strokeWidth',
value: this.numToStr(this.strokeWidth)
},
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Normal is drawable.
*/
GeoNormal.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoNormal
{ // GeoParallel
/**
* Constructor for geometric parallel object.
*/
var GeoParallel = function(params, geoparent) {
this.type = 'Parallel';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoParallel.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoParallel.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'name' : (typeof this.name !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'color' : this.color || '#0000ff',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
}
/**
* Get data of GeoParallel
**/
GeoParallel.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
dash: this.dash,
showName: this.showName,
visible: this.visible,
color: this.color,
strokeWidth: this.strokeWidth
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoParallel.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoParallel.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u2225</i>(<i>'+this.getObjName(this.p1)+'</i>,<i>'+this.getObjName(this.p2)+'</i>)</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoParallel.prototype.iconCSS = 'parallelBtn';
GeoParallel.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-parallel"><line style="stroke: blue;" x1="0" y1="16" x2="12" y2="0" /><line style="stroke: black;" x1="20" y1="4" x2="8" y2="20" /><circle style="stroke: none; fill: red;" cx="6" cy="8" r="2" /></svg>';
/**
* Draw the parallel on board in the construction.
**/
GeoParallel.prototype.asConstruct = function(board, construction) {
var geoparallel = this;
var parallel = board.create(
'parallel',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
straightFirst : true,
straightLast : true,
dash : this.dash,
strokeWidth : this.strokeWidth,
color : this.color
}
);
construction.lines.push(parallel);
parallel.on('up', function(event){
var line = this;
var updoptions = {name: geoparallel.name, geoid: [geoparallel.p1, geoparallel.p2]};
$(parallel.board.containerObj).trigger('objectupdate', [updoptions]);
});
parallel.on('down', function(event){
var parallel = this;
var options = {name: geoparallel.name, geoid: geoparallel.geoid};
$(parallel.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoParallel.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Linelike':
list.push({id: this.geoid, name: this.name});
break;
case 'Parallel':
list.push({id: this.geoid, name: this.name});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoParallel.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var curvelist = this.geoparent.getCurves();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Curve',
key: 'p1',
value: this.p1,
data: curvelist
},
{
type: 'Select',
label: 'Point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
},
{
type: 'Select',
label: 'Line type',
key: 'lineType',
value: this.lineType,
data: [
{id: 'line', name: 'Line'},
{id: 'lineSegment', name: 'Line segment'},
{id: 'startingLine', name: 'Starting line segment'},
{id: 'endingLine', name: 'Ending line segment'}
]
}
],
advanced: [
{
type: 'Text',
label: 'Stroke width',
key: 'strokeWidth',
value: this.numToStr(this.strokeWidth)
},
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Parallel is drawable.
*/
GeoParallel.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoParallel
{ // GeoTangent
/**
* Constructor for geometric tangent object.
*/
var GeoTangent = function(params, geoparent) {
this.type = 'Tangent';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoTangent.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoTangent.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'i1Name': (typeof this.i1Name !== 'undefined' ? this.i1Name : null),
'i2Name': (typeof this.i2Name !== 'undefined' ? this.i2Name : null),
'name' : (typeof this.name !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof this.showName !== 'undefined' ? this.showName : true),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'color' : this.color || '#0000ff',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.i1Name = params.i1Name;
this.i2Name = params.i2Name;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name || this.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
}
/**
* Get data of GeoTangent
**/
GeoTangent.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
i1Name: this.i1Name,
i2Name: this.i2Name,
dash: this.dash,
showName: this.showName,
visible: this.visible,
color: this.color,
strokeWidth: this.strokeWidth
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoTangent.prototype.getDeps = function(){
return [this.p1, this.p2];
}
/**
* Get list string (to be shown in the object list)
**/
GeoTangent.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>T</i>(<i>'+this.getObjName(this.p1)+'</i>,<i>'+this.getObjName(this.p2)+'</i>)</span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoTangent.prototype.iconCSS = 'tangentBtn';
GeoTangent.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-tangent"><path style="fill: none; stroke: black;" d="M0 16 a8 8 0 0 0 8.5 -16" /><line style="stroke: blue;" x1="20" y1="4" x2="8" y2="20" /><circle style="stroke: none; fill: red;" cx="12.5" cy="13" r="2" /></svg>';
/**
* Draw the normal on board in the construction.
**/
GeoTangent.prototype.asConstruct = function(board, construction) {
var geotangent = this;
var jsxpoint = board.objects[this.p2];
var jsxcurve = board.objects[this.p1];
if (((jsxpoint.elType === 'glider' || jsxpoint.elType === 'intersection') && jsxpoint.ancestors[this.p1]) ||
(jsxcurve.elType === 'circle' && jsxpoint.elType === 'point' && jsxcurve.ancestors[this.p2])) {
var tangent1 = board.create(
'tangent',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
id : this.geoid,
dash: this.dash,
strokeWidth: this.strokeWidth,
color: this.color
}
);
} else {
var helpline1 = board.create(
'tangent',
[this.p1, this.p2],
{
// Options here.
visible : false,
name : '',
id : this.geoid + '_helpline1',
straightFirst : true,
straightLast : true
}
);
this.intpoint1 = board.create(
'intersection',
[this.p1, helpline1, 0],
{
visible: this.visible,
id: this.geoid + '-intersection1',
face: '+',
size: 6
}
);
this.i1Name = this.intpoint1.name;
this.intpoint2 = board.create(
'intersection',
[this.p1, helpline1, 1],
{
visible: this.visible,
id: this.geoid + '-intersection2',
face: '+',
size: 6
}
);
this.i2Name = this.intpoint2.name;
var tangent1 = board.create(
'line',
[this.p2, this.intpoint1],
{
visible: this.visible,
id: this.geoid + '-1',
name: this.name + '1',
color: this.color,
strokeWidth: this.strokeWidth,
dash: this.dash
}
);
var tangent2 = board.create(
'line',
[this.p2, this.intpoint2],
{
visible: this.visible,
id: this.geoid + '-2',
name: this.name + '2',
color: this.color,
strokeWidth: this.strokeWidth,
dash: this.dash
}
);
}
construction.lines.push(tangent1);
tangent2 && construction.lines.push(tangent2);
tangent1.on('up', function(event){
var line = this;
var updoptions = {name: geotangent.name, geoid: [geotangent.p1, geotangent.p2]};
$(tangent1.board.containerObj).trigger('objectupdate', [updoptions]);
});
tangent2 && tangent2.on('up', function(event){
var line = this;
var updoptions = {name: geotangent.name, geoid: [geotangent.p1, geotangent.p2]};
$(tangent2.board.containerObj).trigger('objectupdate', [updoptions]);
});
tangent1.on('down', function(event){
var normal = this;
var options = {name: geotangent.name, geoid: geotangent.geoid};
$(tangent1.board.containerObj).trigger('objectselected', [options]);
});
tangent2 && tangent2.on('down', function(event){
var normal = this;
var options = {name: geotangent.name, geoid: geotangent.geoid};
$(tangent2.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Get list of elements of given type.
**/
GeoTangent.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Point':
this.intpoint1 && list.push({id: this.geoid + '-intersection1', name: this.i1Name});
this.intpoint2 && list.push({id: this.geoid + '-intersection2', name: this.i2Name});
break;
case 'Linelike':
list.push({id: this.geoid, name: this.name});
break;
case 'Tangent':
list.push({id: this.geoid + '_1', name: this.name + '1'});
list.push({id: this.geoid + '_2', name: this.name + '2'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoTangent.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var curvelist = this.geoparent.getCurves();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'Curve',
key: 'p1',
value: this.p1,
data: curvelist
},
{
type: 'Select',
label: 'Point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Text',
label: 'Intersection 1 name',
key: 'i1name',
value: this.i1name
},
{
type: 'Text',
label: 'Intersection 2 name',
key: 'i2name',
value: this.i2name
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
},
{
type: 'Select',
label: 'Line type',
key: 'lineType',
value: this.lineType,
data: [
{id: 'line', name: 'Line'},
{id: 'lineSegment', name: 'Line segment'},
{id: 'startingLine', name: 'Starting line segment'},
{id: 'endingLine', name: 'Ending line segment'}
]
}
],
advanced: [
{
type: 'Text',
label: 'Stroke width',
key: 'strokeWidth',
value: this.numToStr(this.strokeWidth)
},
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Tangent is drawable.
*/
GeoTangent.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoTangent
{ // GeoRectangle
/**
* Constructor for geometric triangle object.
*/
var GeoRectangle = function(params, geoparent) {
this.type = 'Rectangle';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoRectangle.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoRectangle.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3dist' : (typeof(this.p3dist) !== 'undefined' ? this.p3dist : null),
'p3name' : (typeof(this.p3name) !== 'undefined' ? this.p3name : null),
'p4name' : (typeof(this.p4name) !== 'undefined' ? this.p4name : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'visible' : (typeof(this.visible) !== 'undefined' ? this.visible : true),
'showP3' : (typeof(this.showP3) !== 'undefined' ? this.showP3 : true),
'showP4' : (typeof(this.showP4) !== 'undefined' ? this.showP4 : true),
'showP3Name' : (typeof(this.showP3Name) !== 'undefined' ? this.showP3Name : true),
'showP4Name' : (typeof(this.showP4Name) !== 'undefined' ? this.showP4Name : true),
'showRightangle' : (typeof this.showRightangle !== 'undefined' ? this.showRightangle : false),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor' : this.fillColor || 'none',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3geoid = this.geoid + '-p3';
this.p4geoid = this.geoid + '-p4';
this.p3dist = this.getDist(params.p3x, params.p3y, params.p3dist);
this.p3name = params.p3name;
this.p4name = params.p4name;
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.showP3 = params.showP3;
this.showP3Name = params.showP3Name;
this.showP4 = params.showP4;
this.showP4Name = params.showP4Name;
this.showRightangle = params.showRightangle;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.angleradius = 0.5;
}
/**
* Get the distance of p3 from p3 with given coordinates of p3.
* The sign + means right from segment p2 p1 and - means left of it.
* The third argument is returned, if x or y is undefined.
**/
GeoRectangle.prototype.getDist = function(x, y, defaultval){
var dist = defaultval;
if (typeof(x) !== 'undefined' && typeof(y) !== 'undefined') {
var sign;
if (this.p1x-this.p2x === 0) {
sign = (x > this.p2x ? +1 : -1);
} else if (this.p1x > this.p2x) {
sign = (y > (this.p1y-this.p2y)/(this.p1x-this.p2x)*(x-this.p1x) + this.p1y ? -1 : 1);
} else {
sign = (y > (this.p1y-this.p2y)/(this.p1x-this.p2x)*(x-this.p1x) + this.p1y ? 1 : -1);
}
var dx = this.p2x - x;
var dy = this.p2y - y;
dist = sign * Math.sqrt(dx*dx + dy*dy);
}
return dist;
}
/**
* Get data of GeoRectangle
**/
GeoRectangle.prototype.getData = function(subid){
if (!subid) {
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3dist: this.p3dist,
p3name: this.p3name,
p4name: this.p4name,
dash: this.dash,
showName: this.showName,
showP3: this.showP3,
showP3Name: this.showP3Name,
showP4: this.showP4,
showP4Name: this.showP4Name,
showRightangle: this.showRightangle,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
labelOffset: this.labelOffset
}
} else {
var data = {};
switch (subid){
case 'side1':
data.type = 'Line';
data.geoid = this.geoid + '-side1';
data.p1 = this.p1;
data.p2 = this.p2;
break;
case 'side2':
data.type = 'Line';
data.geoid = this.geoid + '-side2';
data.p1 = this.p2;
data.p2 = this.geoid + '-p3';
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side3';
data.p1 = this.p3geoid;
data.p2 = this.p4geoid;
break;
case 'side4':
data.type = 'Line';
data.geoid = this.geoid + '-side4';
data.p1 = this.p4geoid;
data.p2 = this.p1;
break;
default:
break
}
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoRectangle.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3geoname];
}
/**
* Get list string (to be shown in the object list)
**/
GeoRectangle.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u25af'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.p3name+this.p4name+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRectangle.prototype.iconCSS = 'rectangleBtn';
GeoRectangle.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-rectangle"><rect style="stroke: blue; fill: none;" x="3" y="5" width="14" height="10" /><circle style="stroke: none; fill: red;" cx="3" cy="5" r="2" /><circle style="stroke: none; fill: red;" cx="17" cy="5" r="2" /><circle style="stroke: none; fill: red;" cx="17" cy="15" r="2" /><circle style="stroke: none; fill: red;" cx="3" cy="15" r="2" /></svg>';
/**
* Update data of the object from the board.
**/
GeoRectangle.prototype.updateFromBoard = function(board){
var p1 = board.objects[this.p1];
var p2 = board.objects[this.p2];
this.p1x = p1.X();
this.p1y = p1.Y();
this.p2x = p2.X();
this.p2y = p2.Y();
var p3 = board.objects[this.p3geoid];
this.p3dist = this.getDist(p3.X(), p3.Y(), this.p3dist);
}
/**
* Draw the rectangle on board in the construction.
**/
GeoRectangle.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var p1 = board.objects[this.p1];
var p2 = board.objects[this.p2];
this.p1x = p1.X();
this.p1y = p1.Y();
this.p2x = p2.X();
this.p2y = p2.Y();
var line1 = board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : '',
id : this.geoid + '-side1',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line1);
var normal1 = board.create(
'normal',
[this.p2, line1],
{
visible : false,
name : '',
id : this.geoid + '-normal1'
}
);
normal1.gedithelpobject = true;
var normal2 = board.create(
'normal',
[this.p1, line1],
{
visible : false,
name : '',
id : this.geoid + '-normal2'
}
);
normal2.gedithelpobject = true;
var dx = p2.X() - p1.X();
var dy = p2.Y() - p1.Y();
var hypot = Math.sqrt(dx*dx + dy*dy);
var ratio = this.p3dist/hypot;
var p3x = p2.X() - dy*ratio;
var p3y = p2.Y() + dx*ratio;
this.p3 = board.create(
'glider',
[p3x, p3y, normal1],
{
visible: this.showP3,
name: (this.showP3Name ? this.p3name : ''),
id: this.p3geoid,
strokeColor: 'red',
fillColor: 'white'
}
);
var normal3 = board.create(
'normal',
[this.p3geoid, normal1],
{
visible: false,
name: '',
id: this.geoid+'-normal3'
}
);
normal3.gedithelpobject = true;
this.p4 = board.create(
'intersection',
[normal2, normal3],
{
visible: this.showP4,
name: (this.showP4Name ? this.p4name : ''),
id: this.p4geoid,
face: '<>',
strokeColor: 'red',
fillColor: 'red'
}
);
var line2 = board.create(
'line',
[this.p2, this.p3],
{
visible : this.visible,
name : '',
id : this.geoid + '-side2',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line2);
var line3 = board.create(
'line',
[this.p3, this.p4],
{
visible : this.visible,
name : '',
id : this.geoid + '-side3',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line3);
var line4 = board.create(
'line',
[this.p4, this.p1],
{
visible : this.visible,
name : '',
id : this.geoid + '-side4',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line4);
var polygon = board.create(
'polygon',
[this.p1, this.p2, this.p3, this.p4],
{
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
);
construction.polygons.push(polygon);
if (this.showRightangle) {
// rangle 1
board.create(
'angle',
[this.p1, this.p2, this.p3],
{
visible: (JXG.Math.Geometry.trueAngle(p1, p2, this.p3).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle11',
name: function(){
board.objects[geoobject.geoid + '_rangle11'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, p2, geoobject.p3).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p3, this.p2, this.p1],
{
visible: (JXG.Math.Geometry.trueAngle(this.p3, p2, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle12',
name: function(){
board.objects[geoobject.geoid + '_rangle12'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geoobject.p3, p2, p1).toFixed(0) < 180)});
return '';
}
}
);
// rangle 2
board.create(
'angle',
[this.p2, this.p3, this.p4],
{
visible: (JXG.Math.Geometry.trueAngle(p1, p2, this.p3).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle21',
name: function(){
board.objects[geoobject.geoid + '_rangle21'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, p2, geoobject.p3).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p4, this.p3, this.p2],
{
visible: (JXG.Math.Geometry.trueAngle(this.p3, p2, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle22',
name: function(){
board.objects[geoobject.geoid + '_rangle22'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geoobject.p3, p2, p1).toFixed(0) < 180)});
return '';
}
}
);
// rangle 3
board.create(
'angle',
[this.p3, this.p4, this.p1],
{
visible: (JXG.Math.Geometry.trueAngle(p1, p2, this.p3).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle31',
name: function(){
board.objects[geoobject.geoid + '_rangle31'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, p2, geoobject.p3).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p1, this.p4, this.p3],
{
visible: (JXG.Math.Geometry.trueAngle(this.p3, p2, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle32',
name: function(){
board.objects[geoobject.geoid + '_rangle32'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geoobject.p3, p2, p1).toFixed(0) < 180)});
return '';
}
}
);
// rangle 4
board.create(
'angle',
[this.p4, this.p1, this.p2],
{
visible: (JXG.Math.Geometry.trueAngle(p1, p2, this.p3).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle41',
name: function(){
board.objects[geoobject.geoid + '_rangle41'].setProperty({visible: (JXG.Math.Geometry.trueAngle(p1, p2, geoobject.p3).toFixed(0) < 180)});
return '';
}
}
);
board.create(
'angle',
[this.p2, this.p1, this.p4],
{
visible: (JXG.Math.Geometry.trueAngle(this.p3, p2, p1).toFixed(0) < 180),
orthoType: 'square',
radius: this.angleradius,
id: this.geoid + '_rangle42',
name: function(){
board.objects[geoobject.geoid + '_rangle42'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geoobject.p3, p2, p1).toFixed(0) < 180)});
return '';
}
}
);
}
this.p3.on('up', function(event){
var point = this;
var p3x = point.X();
var p3y = point.Y();
geoobject.setData({p3x: p3x, p3y: p3y});
$(point.board.containerObj).trigger('objectupdate', [{name: geoobject.name, geoid: []}]);
});
line1.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p2, geoobject.geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line2.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p2, geoobject.p3geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line3.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p3geoid, geoobject.p4geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line4.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p4geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line3.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line4.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoRectangle.prototype.select = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: true, strokeWidth: this.strokeWidth * 2});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: true});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: true});
board.objects[this.geoid + '-side4'] && board.objects[this.geoid + '-side4'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoRectangle.prototype.deselect = function(board){
board.objects[this.geoid + '-side1'] && board.objects[this.geoid + '-side1'].setProperty({shadow: false, strokeWidth: this.strokeWidth});
board.objects[this.geoid + '-side2'] && board.objects[this.geoid + '-side2'].setProperty({shadow: false});
board.objects[this.geoid + '-side3'] && board.objects[this.geoid + '-side3'].setProperty({shadow: false});
board.objects[this.geoid + '-side4'] && board.objects[this.geoid + '-side4'].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoRectangle.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Rectangle':
list.push({id: this.geoid, name: this.name});
break;
case 'Point':
list.push({id: this.p3geoid, name: this.p3name});
list.push({id: this.p4geoid, name: this.p4name});
break;
case 'Linelike':
list.push({id: this.geoid + '-side1', name: this.name + '_1'});
list.push({id: this.geoid + '-side2', name: this.name + '_2'});
list.push({id: this.geoid + '-side3', name: this.name + '_3'});
list.push({id: this.geoid + '-side4', name: this.name + '_4'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoRectangle.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Text',
label: 'Third point name',
key: 'p3name',
value: this.p3name
},
{
type: 'Text',
label: 'Fourth point name',
key: 'p4name',
value: this.p4name
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Show third point',
key: 'showP3',
value: this.showP3
},
{
type: 'Checkbox',
label: 'Show third point name',
key: 'showP3Name',
value: this.showP3Name
},
{
type: 'Checkbox',
label: 'Show fourth point',
key: 'showP4',
value: this.showP4
},
{
type: 'Checkbox',
label: 'Show fourth point name',
key: 'showP4Name',
value: this.showP4Name
},
{
type: 'Checkbox',
label: 'Show right angle',
key: 'showRightangle',
value: this.showRightangle
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Rectangle is drawable.
*/
GeoRectangle.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2];
}
} // End GeoRectangle
{ // GeoParallelogram
/**
* Constructor for geometric Parallelogram object.
*/
var GeoParallelogram = function(params, geoparent) {
this.type = 'Parallelogram';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoParallelogram.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoParallelogram.prototype.setData = function(params){
params = $.extend( {
'p1' : this.p1 || null,
'p2' : this.p2 || null,
'p3' : this.p3 || null,
'p4name' : (typeof(this.p4name) !== 'undefined' ? this.p4name : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'dash' : this.dash || 0,
'visible' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'showName' : (typeof(this.showName) !== 'undefined' ? this.showName : true),
'showP4' : (typeof(this.showP4) !== 'undefined' ? this.showP4 : true),
'showP4Name' : (typeof(this.showP4Name) !== 'undefined' ? this.showP4Name : true),
'strokeColor' : this.strokeColor || '#0000ff',
'fillColor' : this.fillColor || 'none',
'strokeWidth' : (typeof(this.strokeWidth) !== 'undefined' ? this.strokeWidth : 2)
}, params);
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.p4name = params.p4name;
this.p4geoid = this.geoid + '-p4';
this.strokeWidth = this.strToNum(params.strokeWidth);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
}
/**
* Get data of GeoParallelogram
**/
GeoParallelogram.prototype.getData = function(subid){
if (!subid) {
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2,
p3: this.p3,
p4name: this.p4name,
showP4: this.showP4,
showP4Name: this.showP4Name,
dash: this.dash,
showName: this.showName,
visible: this.visible,
strokeColor: this.strokeColor,
fillColor: this.fillColor,
labelOffset: this.labelOffset
}
} else {
var data = {};
switch (subid){
case 'side1':
data.type = 'Line';
data.geoid = this.geoid + '-side1';
data.p1 = this.p1;
data.p2 = this.p2;
break;
case 'side2':
data.type = 'Line';
data.geoid = this.geoid + '-side2';
data.p1 = this.p2;
data.p2 = this.p3;
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side3';
data.p1 = this.p3;
data.p2 = this.p4geoid;
break;
case 'side3':
data.type = 'Line';
data.geoid = this.geoid + '-side4';
data.p1 = this.p4geoid;
data.p2 = this.p1;
break;
default:
break
}
}
return data;
}
/**
* Get the list of dependencies.
**/
GeoParallelogram.prototype.getDeps = function(){
return [this.p1, this.p2, this.p3];
}
/**
* Get list string (to be shown in the object list)
**/
GeoParallelogram.prototype.getListStr = function(){
var str = '<div class="gedit-listicon" title="'+this.type+'">' + this.icon + '</div><div class="gedit-listname"><i>' + this.getNameFormatted() + '</i><span class="geoedit-aka">=<i>\u25b1'+this.getObjName(this.p1)+this.getObjName(this.p2)+this.getObjName(this.p3)+this.p4name+'</i></span></div>';
return str;
}
/**
* CSS style defining the icon representing this type.
**/
GeoParallelogram.prototype.iconCSS = 'parallelogramBtn';
GeoParallelogram.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-object-parallelogram"><path style="stroke: blue; fill: none;" d="M4 6 l13 -2 l-1 10 l-13 2z" /><circle style="stroke: none; fill: red;" cx="4" cy="6" r="2" /><circle style="stroke: none; fill: red;" cx="17" cy="4" r="2" /><circle style="stroke: none; fill: red;" cx="16" cy="14" r="2" /><circle style="stroke: none; fill: red;" cx="3" cy="16" r="2" /></svg>';
/**
* Draw the parallelogram on board in the construction.
**/
GeoParallelogram.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var p4 = board.create(
'parallelpoint',
[this.p2, this.p1, this.p3],
{
visible: this.visible,
name: this.p4name,
id: this.p4geoid,
face: '<>',
size: 5,
strokeColor: 'none',
fillColor: '#ff0000'
}
)
var line1 = board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : '',
id : this.geoid + '-side1',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line1);
var line2 = board.create(
'line',
[this.p2, this.p3],
{
visible : this.visible,
name : '',
id : this.geoid + '-side2',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line2);
var line3 = board.create(
'line',
[this.p3, this.p4geoid],
{
visible : this.visible,
name : '',
id : this.geoid + '-side3',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line3);
var line4 = board.create(
'line',
[this.p4geoid, this.p1],
{
visible : this.visible,
name : '',
id : this.geoid + '-side4',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
construction.lines.push(line4);
var polygon = board.create(
'polygon',
[this.p1, this.p2, this.p3, this.p4geoid],
{
visible : this.visible,
name : this.name,
id : this.geoid,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
);
construction.polygons.push(polygon);
line1.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p1, geoobject.p2]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line2.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p2, geoobject.p3]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line3.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p3, geoobject.p4geoid]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line4.on('up', function(event){
var line = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.p4geoid, geoobject.p1]};
$(line.board.containerObj).trigger('objectupdate', [updoptions]);
});
line1.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line2.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line3.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
line4.on('down', function(event){
var line = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(line.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Select this object.
**/
GeoParallelogram.prototype.select = function(board){
board.objects[this.geoid + '-side1'].setProperty({shadow: true});
board.objects[this.geoid + '-side2'].setProperty({shadow: true});
board.objects[this.geoid + '-side3'].setProperty({shadow: true});
board.objects[this.geoid + '-side4'].setProperty({shadow: true});
}
/**
* Deselect this object.
**/
GeoParallelogram.prototype.deselect = function(board){
board.objects[this.geoid + '-side1'].setProperty({shadow: false});
board.objects[this.geoid + '-side2'].setProperty({shadow: false});
board.objects[this.geoid + '-side3'].setProperty({shadow: false});
board.objects[this.geoid + '-side4'].setProperty({shadow: false});
}
/**
* Get list of elements of given type.
**/
GeoParallelogram.prototype.getOfType = function(otype){
var list = [];
switch (otype){
case 'Parallelogram':
list.push({id: this.geoid, name: this.name});
break;
case 'Point':
list.push({id: this.p4geoid, name: this.p4name});
break;
case 'Linelike':
list.push({id: this.geoid + '-side1', name: this.name + '_1'});
list.push({id: this.geoid + '-side2', name: this.name + '_2'});
list.push({id: this.geoid + '-side3', name: this.name + '_3'});
list.push({id: this.geoid + '-side4', name: this.name + '_4'});
break;
default:
break;
}
return list;
}
/**
* Get the html for options dialog.
**/
GeoParallelogram.prototype.getOptionsDialog = function() {
var pointlist = this.geoparent.getPointlikes();
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Select',
label: 'First point',
key: 'p1',
value: this.p1,
data: pointlist
},
{
type: 'Select',
label: 'Second point',
key: 'p2',
value: this.p2,
data: pointlist
},
{
type: 'Select',
label: 'Third point',
key: 'p3',
value: this.p3,
data: pointlist
},
{
type: 'Color',
label: 'Stroke color',
key: 'strokeColor',
value: this.strokeColor
},
{
type: 'Color',
label: 'Fill color',
key: 'fillColor',
value: this.fillColor
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Show label',
key: 'showName',
value: this.showName
},
{
type: 'Checkbox',
label: 'Show fourth point',
key: 'showP4',
value: this.showP4
},
{
type: 'Checkbox',
label: 'Show fourth point name',
key: 'showP4Name',
value: this.showP4Name
}
]
}
var dashDialog = {
type: 'Select',
label: 'Line style',
key: 'dash',
value: this.dash,
data: []
}
for (var i = 0; i < this.dashTypes.length; i++) {
dashDialog.data.push({id: i, name: this.dashTypes[i]});
}
dialog.advanced.push(dashDialog);
return dialog;
}
/**
* Tell, if Parallelogram is drawable.
*/
GeoParallelogram.prototype.drawable = function(board){
return !!board.objects[this.p1] && !!board.objects[this.p2] && !!board.objects[this.p3];
}
} // End GeoParallelogram
{ // GeoLabel
/**
* Constructor for geometric point object.
*/
var GeoLabel = function(params, geoparent) {
this.type = 'Label';
this.geoid = params.geoid;
this.geoparent = geoparent;
this.setData(params);
}
/**
* Inherit the prototype of GeoObject.
*/
GeoLabel.prototype = new GeoObject();
/**
* Set data from given object.
*/
GeoLabel.prototype.setData = function(params){
params = $.extend( {
'x' : (typeof(this.x) !== 'undefined' ? this.x : null),
'y' : (typeof(this.y) !== 'undefined' ? this.y : null),
'name' : (typeof(this.name) !== 'undefined' ? this.name : null),
'value' : (typeof this.value !== 'undefined' ? this.value : ''),
'visible' : (typeof this.visible !== 'undefined' ? this.visible : true),
'fixed' : (typeof this.fixed !== 'undefined' ? this.fixed : false),
'fontSize' : (typeof this.fontSize !== 'undefined' ? this.fontSize : 14),
'color' : this.color || '#000000',
'snapToGrid' : this.snapToGrid || false
}, params);
this.fontSize = this.strToNum(params.fontSize);
this.x = this.strToNum(params.x);
this.y = this.strToNum(params.y);
this.name = params.name;
this.value = params.value;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
this.snapToGrid = params.snapToGrid;
}
/**
* Get data of GeoLabel
**/
GeoLabel.prototype.getData = function(){
var data = {
type: this.type,
name: this.name,
geoid: this.geoid,
x: this.x,
y: this.y,
value: this.value,
visible: this.visible,
fixed: this.fixed,
fontSize: this.fontSize,
color: this.color,
snapToGrid: this.snapToGrid
}
return data;
}
/**
* CSS style defining the icon representing this type.
**/
GeoLabel.prototype.iconCSS = 'labelBtn';
GeoLabel.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="geoedit-icon geoedit-object-label"><text style="fill: #00a; font-family: serif; font-size: 18px; font-weight: bold;" x="2" y="22">Ab</text></svg>';
/**
* Draw the label on board in the construction.
*/
GeoLabel.prototype.asConstruct = function(board, construction) {
var geoobject = this;
var p = board.create(
'text',
[this.x, this.y, this.value],
{
name : this.name,
id : this.geoid,
fontSize : this.fontSize,
visible : this.visible,
fixed : this.fixed,
color: (!this.fixed ? this.color : '#000000'),
snapToGrid: this.snapToGrid
}
);
if (!this.name) {
this.name = p.name;
}
p.on('up', function(event){
var obj = this;
var updoptions = {name: geoobject.name, geoid: [geoobject.geoid]};
$(obj.board.containerObj).trigger('objectupdate', [updoptions]);
var options = {
name: geoobject.name,
x: Math.round(obj.X() * 100)/100,
y: Math.round(obj.Y() * 100)/100,
element: geoobject
};
$(obj.board.containerObj).trigger('objectmoved', [options]);
});
p.on('down', function(event){
var obj = this;
var options = {name: geoobject.name, geoid: geoobject.geoid};
$(obj.board.containerObj).trigger('objectselected', [options]);
});
}
/**
* Update data of the object from the board.
**/
GeoLabel.prototype.updateFromBoard = function(board){
var obj = board.objects[this.geoid];
this.x = Math.round(obj.X() * 100)/100;
this.y = Math.round(obj.Y() * 100)/100;
}
/**
* Get list of elements of given type.
**/
GeoLabel.prototype.getOfType = function(otype){
var list = [];
if (otype === 'Label') {
list.push({id: this.geoid, name: this.name});
}
return list;
}
/**
* Get the object for options dialog.
*/
GeoLabel.prototype.getOptionsDialog = function() {
var dialog = {
basic: [
{
type: 'Label',
label: 'Id',
key: '',
value: this.geoid
},
{
type: 'Text',
label: 'Label',
key: 'name',
value: this.name
},
{
type: 'Text',
label: 'Caption',
key: 'value',
value: this.value
},
{
type: 'Text',
label: 'x-coordinate',
key: 'x',
value: this.numToStr(this.x)
},
{
type: 'Text',
label: 'y-coordinate',
key: 'y',
value: this.numToStr(this.y)
},
{
type: 'Color',
label: 'Color',
key: 'color',
value: this.color
}
],
advanced: [
{
type: 'Checkbox',
label: 'Visible',
key: 'visible',
value: this.visible
},
{
type: 'Checkbox',
label: 'Fixed',
key: 'fixed',
value: this.fixed
},
{
type: 'Checkbox',
label: 'Snap to grid',
key: 'snapToGrid',
value: this.snapToGrid
},
{
type: 'Text',
label: 'Text size',
key: 'fontSize',
value: this.fontSize
}
]
}
return dialog;
}
} // End GeoLabel
}
{ /*** GeoTools ***************************************************************/
{ // Virtual GeoTool
/***************
* Virtual GeoTool class, that can be inherited
***************/
var GeoTool = function(geoparent){
this.type = 'General GeoTool'
}
GeoTool.prototype.init = function(){
this.steps = 0;
this.currStep = 0;
}
/**
* Subtool list
**/
GeoTool.prototype.subtools = [];
/**
* Get the icon of GeoTool;
**/
GeoTool.prototype.getIcon = function(){
return this.icon;
}
/**
* Get the type of GeoTool.
**/
GeoTool.prototype.getType = function(){
return this.type;
}
/**
* Get the name of object with given geoid.
**/
GeoTool.prototype.getObjName = function(name){
return this.geoparent.getObjName(name);
}
/**
* Action for click on board.
**/
GeoTool.prototype.click = function(){
return true;
}
/**
* Find all points in (near) given coordinates in given board. Return namelist.
**/
GeoTool.prototype.getPointsInCoords = function(board, coords){
var points = [];
for (var el in board.objects){
var element = board.objects[el];
if (element.name === 'gedithiddenmousecursor') {
continue;
}
if (JXG.isPoint(element) && !element.id.match(/^jxgBoard/) && element.hasPoint(coords.scrCoords[1], coords.scrCoords[2])) {
points.push(element);
}
}
return points;
}
/**
* Find all lines in (near) given coordinates in given board. Return namelist.
**/
GeoTool.prototype.getLinesInCoords = function(board, coords){
var gelements = [];
for (var el in board.objects){
var element = board.objects[el];
if (!element.gedithelpobject &&
(element.elType === 'line' || element.elType === 'normal' || element.elType === 'parallel' || element.elType === 'tangent')
&& !element.id.match(/^jxgBoard/)
&& element.hasPoint(coords.scrCoords[1], coords.scrCoords[2])) {
gelements.push(element);
}
}
return gelements;
}
/**
* Find all lines, circles, arcs, parallel, normal, axis,... in (near) given coordinates in given board. Return namelist.
**/
GeoTool.prototype.getElementsInCoords = function(board, coords){
var gelements = [];
for (var el in board.objects){
var element = board.objects[el];
if (!element.id.match(/^jxgBoard/) &&
(element.elType === 'line' ||
element.elType === 'circle' ||
element.elType === 'parallel' ||
element.elType === 'bisector' ||
element.elType === 'normal' ||
element.elType === 'axis')
&& element.getProperty('visible')
&& element.hasPoint(coords.scrCoords[1], coords.scrCoords[2])) {
gelements.push(element);
}
}
return gelements;
}
/**
* Send updateinfo-event with message.
**/
GeoTool.prototype.sendInfo = function(board, message){
message = this.type + '-' + message || '';
$(board.containerObj).trigger('updateinfo', [message]);
}
/**
* Tool info
**/
GeoTool.prototype.info = {};
} // End GeoTool
{ // GeoToolSelect
/****************************************
* GeoToolSelect - Tool for selecting and moving objects.
****************************************/
var GeoToolSelect = function(geoparent){
this.type = 'Select';
//this.lang = lang;
this.geoparent = geoparent;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolSelect);
/**
* Inherit the virtual GeoTool.
**/
GeoToolSelect.prototype = new GeoTool();
/**
* Icon for select tool
**/
GeoToolSelect.prototype.icon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="geoedit-icon geoedit-tool-pointer"><path style="stroke: black; stroke-width: 1px; fill: white;" d="M4 4 l11 3 l-2 3 l5 5 l-3 3 l-5 -5 l-3 2z" /></svg>';
} // End GeoToolSelect
{ // GeoToolPoint
/****************************************
* GeoToolPoint - Tool for creating points.
****************************************/
var GeoToolPoint = function(geoparent){
this.type = 'Point';
this.geoparent = geoparent;
this.steps = 1;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolPoint);
/**
* Inherit the virtual GeoTool.
**/
GeoToolPoint.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolPoint.prototype.subtools = [];
/**
* Icon for point tool. - Use the same icon as for GeoPoint-object.
**/
GeoToolPoint.prototype.icon = GeoPoint.prototype.icon;
/**
* Init the GeoToolPoint. Reset the stepnumber etc.
**/
GeoToolPoint.prototype.init = function(){
this.step = 0;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolPoint.prototype.click = function(data){
this.currStep = 0;
return [{
type: 'Point',
x: Math.round(data.xcoord * 100)/100,
y: Math.round(data.ycoord * 100)/100
}];
}
} // End GeoToolPoint
{ // GeoToolLine
/****************************************
* GeoToolLine - Tool for creating lines.
****************************************/
var GeoToolLine = function(geoparent){
this.type = 'Line';
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolLine);
/**
* Inherit the virtual GeoTool.
**/
GeoToolLine.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolLine.prototype.subtools = [];
/**
* Icon for line tool. - Use the same icon as for GeoLine-object.
**/
GeoToolLine.prototype.icon = GeoLine.prototype.icon;
/**
* Init the GeoToolLine. Reset the stepnumber etc.
**/
GeoToolLine.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.line = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolLine.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
return [];
}
break;
case 2:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
//this.p2.remove();
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line.remove();
this.line = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
this.linegeoid = this.geoparent.getObjId('Line');
this.result.push({type: 'Line', name: this.line.name, geoid: this.linegeoid, p1: this.p1geoid, p2: this.p2geoid});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.linegeoid = this.geoparent.getObjId('Line');
this.result.push({type: 'Line', name: this.line.name, geoid: this.linegeoid, p1: this.p1geoid, p2: this.p2geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolLine
{ // GeoToolCircle
/****************************************
* GeoToolCircle - Tool for creating circles.
****************************************/
var GeoToolCircle = function(geoparent){
this.type = 'Circle';
this.geoparent = geoparent;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolCircle);
/**
* Inherit the virtual GeoTool.
**/
GeoToolCircle.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolCircle.prototype.subtools = [];
/**
* Icon for Circle tool. - Use the same icon as for GeoCircle-object.
**/
GeoToolCircle.prototype.icon = GeoCircle.prototype.icon;
/**
* Init the GeoToolCircle. Reset the stepnumber etc.
**/
GeoToolCircle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.circle = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolCircle.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.result = [];
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.circle = board.create('Circle', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.circle = board.create('Circle', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
return [];
}
break;
case 2:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.circle.remove();
this.circle = board.create('Circle', [this.p1, this.p2], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
this.circlegeoid = this.geoparent.getObjId('Circle');
this.result.push({type: 'Circle', name: this.circle.name, geoid: this.circlegeoid, p1: this.p1geoid, p2: this.p2geoid});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.circlegeoid = this.geoparent.getObjId('Circle');
this.result.push({type: 'Circle', name: this.circle.name, geoid: this.circlegeoid, p1: this.p1geoid, p2: this.p2geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolCircle
{ // GeoToolRcircle
/****************************************
* GeoToolRcircle - Tool for creating circles with segment as radius.
****************************************/
var GeoToolRcircle = function(geoparent){
this.type = 'Rcircle';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolRcircle);
GeoToolCircle.prototype.subtools.push('Rcircle');
/**
* Inherit the virtual GeoTool.
**/
GeoToolRcircle.prototype = new GeoTool();
/**
* Icon for Rcircle tool. - Use the same icon as for GeoRcircle-object.
**/
GeoToolRcircle.prototype.icon = GeoRcircle.prototype.icon;
/**
* Init the GeoToolRcircle. Reset the stepnumber etc.
**/
GeoToolRcircle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.p1fake = null;
this.circle = null;
this.fakeradius = null;
this.fakecircle = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolRcircle.prototype.click = function(data){
var ctool = this;
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.result = [];
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', showLabel: false, size: 5, id: this.p1geoid});
this.p1fake = this.p1;
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.p1fake = board.create('Point', [this.p1.X(), this.p1.Y()], {fillColor: 'none', strokeColor: 'black', face: 'x', size: 5, name: '', id: this.p1geoid+'_fake'});
return [];
}
break;
case 2:
var lines = this.getLinesInCoords(board, coords);
var points = this.getPointsInCoords(board, coords);
if (points.length > 0) {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.fakeradius = board.create('Line', [this.p2, 'gedithiddenmousecursor'], {visible: false});
this.fakecircle = board.create('Circle', [this.p1fake, this.fakeradius], {strokeColor: 'gray', strokeWidth: 1, id: this.geoid+'fake', name: ''});
this.sendInfo(board, '2');
return [];
} else if (lines.length > 0) {
var linedata = this.geoparent.getObjDataById(lines[0].id);
if (linedata) {
this.p2geoid = linedata.p1;
this.p3geoid = linedata.p2;
this.circlegeoid = this.geoparent.getObjId('Rcircle');
this.circle = board.create('Circle', [this.p1, board.objects[linedata.geoid]], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Rcircle', name: this.circle.name, geoid: this.circlegeoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
this.sendInfo(board, 'start');
this.currStep = 0;
}
} else {
this.currStep--;
this.sendInfo(board, 'error-'+this.currStep);
return [];
};
break;
case 3:
var points = this.getPointsInCoords(board, coords);
if (points.length > 0) {
this.p3 = points[0];
this.p3geoid = this.p3.id;
this.circlegeoid = this.geoparent.getObjId('Rcircle');
var radius = this.p2.Dist(this.p3);
this.circle = board.create('Circle', [this.p1, radius], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Rcircle', name: this.circle.name, geoid: this.circlegeoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
this.sendInfo(board, 'start');
this.currStep = 0;
} else {
this.currStep--;
this.sendInfo(board, 'error-'+this.currStep);
return [];
};
break;
default:
this.currStep = this.currStep - 1;
this.sendInfo(board, 'error-'+this.currStep);
this.result = [];
}
return this.result;
}
} // End GeoToolRcircle
{ // GeoToolTriangle
/****************************************
* GeoToolTriangle - Tool for creating triangles.
****************************************/
var GeoToolTriangle = function(geoparent){
this.type = 'Triangle';
this.geoparent = geoparent;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolTriangle);
/**
* Inherit the virtual GeoTool.
**/
GeoToolTriangle.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolTriangle.prototype.subtools = [];
/**
* Icon for triangle tool. - Use the same icon as for GeoTriangle-object.
**/
GeoToolTriangle.prototype.icon = GeoTriangle.prototype.icon;
/**
* Init the GeoToolTriangle. Reset the stepnumber etc.
**/
GeoToolTriangle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.line1 = null;
this.line2 = null;
this.line3 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolTriangle.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.line2 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p2, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.line2 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p2, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
}
return [];
break;
case 3:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p3geoid = this.geoparent.getObjId('Point');
this.p3 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p3geoid});
//this.line1.remove();
//this.line2.remove();
//this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p3.name, geoid: this.p3geoid, x: data.xcoord, y: data.ycoord});
this.trianglegeoid = this.geoparent.getObjId('Triangle');
this.result.push({type: 'Triangle', name: '\u25b3'+this.p1.name+this.p2.name+this.p3.name, geoid: this.trianglegeoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
} else {
this.p3 = points[0];
this.p3geoid = this.p3.id;
this.trianglegeoid = this.geoparent.getObjId('Triangle');
this.result.push({type: 'Triangle', name: '\u25b3'+this.p1.name+this.p2.name+this.p3.name, geoid: this.trianglegeoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolTriangle
{ // GeoToolRighttriangle
/****************************************
* GeoToolRighttriangle - Tool for creating right triangles.
****************************************/
var GeoToolRighttriangle = function(geoparent){
this.type = 'Righttriangle';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolRighttriangle);
GeoToolTriangle.prototype.subtools.push('Righttriangle');
/**
* Inherit the virtual GeoTool.
**/
GeoToolRighttriangle.prototype = new GeoTool();
/**
* Icon for right triangle tool. - Use the same icon as for GeoRighttriangle-object.
**/
GeoToolRighttriangle.prototype.icon = GeoRighttriangle.prototype.icon;
/**
* Init the GeoToolRighttriangle. Reset the stepnumber etc.
**/
GeoToolRighttriangle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.line1 = null;
this.line2 = null;
this.line3 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolRighttriangle.prototype.click = function(data){
var geotool = this;
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var midpoint = board.create('midpoint', [this.p1, this.p2], {visible: false});
var circle = board.create('circle', [midpoint, this.p1], {visible: false});
var helpline = board.create('line', [midpoint, 'gedithiddenmousecursor'], {visible: false, strokeColor: 'gray'});
this.p3 = board.create('intersection', [helpline, circle, 0], {visible: true, color: 'gray', name: '', face: 'x'});
this.line2 = board.create('Line', [this.p1, this.p3], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p2, this.p3], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
var helpangle1 = board.create('angle', [this.p1, this.p3, this.p2], {
orthoType: 'square',
strokeColor: 'gray',
fillColor: 'gray',
fillOpacity: 0.3,
radius: 0.5,
id: this.geoid + '_helpangle1',
name: function(){
board.objects[geotool.geoid + '_helpangle1'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geotool.p1, geotool.p3, geotool.p2).toFixed(0) < 180)});
return '';
}
});
var helpangle2 = board.create('angle', [this.p2, this.p3, this.p1], {
orthoType: 'square',
strokeColor: 'gray',
fillColor: 'gray',
fillOpacity: 0.3,
radius: 0.5,
id: this.geoid + '_helpangle2',
name: function(){
board.objects[geotool.geoid + '_helpangle2'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geotool.p2, geotool.p3, geotool.p1).toFixed(0) < 180)});
return '';
}
});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var midpoint = board.create('midpoint', [this.p1, this.p2], {visible: false, name: ''});
var circle = board.create('circle', [midpoint, this.p1], {visible: false});
var helpline = board.create('line', [midpoint, 'gedithiddenmousecursor'], {visible: false, strokeColor: 'gray'});
this.p3 = board.create('intersection', [helpline, circle, 0], {visible: true, color: 'gray', name: '', face: 'x'});
this.line2 = board.create('Line', [this.p1, this.p3], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p2, this.p3], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
var helpangle1 = board.create('angle', [this.p1, this.p3, this.p2], {
orthoType: 'square',
strokeColor: 'gray',
fillColor: 'gray',
fillOpacity: 0.3,
radius: 0.5,
id: this.geoid + '_helpangle1',
name: function(){
board.objects[geotool.geoid + '_helpangle1'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geotool.p1, geotool.p3, geotool.p2).toFixed(0) < 180)});
return '';
}
});
var helpangle2 = board.create('angle', [this.p2, this.p3, this.p1], {
orthoType: 'square',
strokeColor: 'gray',
fillColor: 'gray',
fillOpacity: 0.3,
radius: 0.5,
id: this.geoid + '_helpangle2',
name: function(){
board.objects[geotool.geoid + '_helpangle2'].setProperty({visible: (JXG.Math.Geometry.trueAngle(geotool.p2, geotool.p3, geotool.p1).toFixed(0) < 180)});
return '';
}
});
}
return [];
break;
case 3:
this.sendInfo(board, 'start');
this.p3x = this.p3.X();
this.p3y = this.p3.Y();
var point3 = board.create('point', [this.p3x, this.p3y], {visible: false});
this.p3name = point3.name;
this.trianglegeoid = this.geoparent.getObjId('Righttriangle');
this.result.push({type: 'Righttriangle', name: '\u25b3'+this.p1.name+this.p2.name, geoid: this.trianglegeoid, p1: this.p1geoid, p2: this.p2geoid, p3x: this.p3x, p3y: this.p3y, p3name: this.p3name});
this.p3.remove();
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolRighttriangle
{ // GeoToolGlider
/****************************************
* GeoToolGlider - Tool for creating gliders.
****************************************/
var GeoToolGlider = function(geoparent){
this.type = 'Glider';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 1;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolGlider);
GeoToolPoint.prototype.subtools.push('Glider');
/**
* Inherit the virtual GeoTool.
**/
GeoToolGlider.prototype = new GeoTool();
/**
* Icon for glider tool. - Use the same icon as for GeoGlider-object.
**/
GeoToolGlider.prototype.icon = GeoGlider.prototype.icon;
/**
* Init the GeoToolGlider. Reset the stepnumber etc.
**/
GeoToolGlider.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.parent = null;
this.glider = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolGlider.prototype.click = function(data){
this.currStep = 0;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
this.sendInfo(board, 'start');
var curves = this.getElementsInCoords(board, coords);
if (curves.length > 0) {
this.parent = curves[0].id;
this.geoid = this.geoparent.getObjId('Glider');
this.glider = board.create('Glider', [this.parent], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.geoid});
return [{
geoid: this.geoid,
name: this.glider.name,
type: 'Glider',
x: Math.round(data.xcoord * 100)/100,
y: Math.round(data.ycoord * 100)/100,
parent: this.parent
}];
}
return [];
}
} // End GeoToolGlider
{ // GeoToolMidpoint
/****************************************
* GeoToolMidpoint - Tool for creating midpoint between two points.
****************************************/
var GeoToolMidpoint = function(geoparent){
this.type = 'Midpoint';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolMidpoint);
GeoToolPoint.prototype.subtools.push('Midpoint');
/**
* Inherit the virtual GeoTool.
**/
GeoToolMidpoint.prototype = new GeoTool();
/**
* Icon for midpoint tool. - Use the same icon as for GeoMidpoint-object.
**/
GeoToolMidpoint.prototype.icon = GeoMidpoint.prototype.icon;
/**
* Init the GeoToolMidpoint. Reset the stepnumber etc.
**/
GeoToolMidpoint.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.midpoint = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolMidpoint.prototype.click = function(data){
this.currStep++;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, 1);
var lines = this.getLinesInCoords(board, coords);
var points = this.getPointsInCoords(board, coords);
if (points.length > 0) {
this.p1 = points[0].id;
this.midpoint = board.create('midpoint',
[this.p1, 'gedithiddenmousecursor'],{
fillColor: 'gray',
strokeColor: 'gray',
face: '<>'
});
this.sendInfo(board, '1');
return [];
} else if (lines.length > 0) {
var line = lines[0];
this.p1 = line.point1.id;
this.p2 = line.point2.id;
this.geoid = this.geoparent.getObjId('Midpoint');
this.midpoint = board.create('midpoint', [this.p1, this.p2], {fillColor: 'gray', strokeColor: 'gray', face: '<>', id: this.geoid});
this.currStep = 0;
this.sendInfo(board, 'start');
return [{
geoid: this.geoid,
name: this.midpoint.name,
type: 'Midpoint',
p1: this.p1,
p2: this.p2
}];
} else {
this.currStep--;
this.sendInfo(board, 'error-'+this.currStep);
return [];
}
break;
case 2:
var points = this.getPointsInCoords(board, coords);
if (points.length > 0) {
this.p2 = points[0].id;
this.midpoint = board.create('midpoint',
[this.p1, this.p2],{
fillColor: 'gray',
strokeColor: 'gray',
face: '<>'
});
this.currStep = 0;
this.sendInfo(board, 'start');
this.geoid = this.geoparent.getObjId('Midpoint');
return [{
type: 'Midpoint',
name: this.midpoint.name,
geoid: this.geoid,
p1: this.p1,
p2: this.p2
}];
} else {
this.currStep--;
this.sendInfo(board, 'error-'+this.currStep);
return [];
}
break;
default:
this.currStep--;
this.sendInfo('board', 'error-'+this.currStep);
break;
}
return [];
}
} // End GeoToolMidpoint
{ // GeoToolIntersection
/****************************************
* GeoToolIntersection - Tool for creating intersections.
****************************************/
var GeoToolIntersection = function(geoparent){
this.type = 'Intersection';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolIntersection);
GeoToolPoint.prototype.subtools.push('Intersection');
/**
* Inherit the virtual GeoTool.
**/
GeoToolIntersection.prototype = new GeoTool();
/**
* Icon for intersection tool. - Use the same icon as for GeoIntersection-object.
**/
GeoToolIntersection.prototype.icon = GeoIntersection.prototype.icon;
/**
* Init the GeoToolIntersection. Reset the stepnumber etc.
**/
GeoToolIntersection.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.parent1 = null;
this.parent2 = null;
this.intersection = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolIntersection.prototype.click = function(data){
this.currStep++;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep) {
case 1:
this.result = [];
var curves = this.getElementsInCoords(board, coords);
if (curves.length > 0) {
this.parent1 = curves[0].id;
this.sendInfo(board, this.currStep);
return [];
} else {
this.currStep--;
this.sendInfo(board, 'start');
return [];
}
break;
case 2:
this.result = [];
var curves = this.getElementsInCoords(board, coords);
if (curves.length > 0) {
this.parent2 = curves[0].id;
//this.intersection = board.create('Intersection', [this.parent1, this.parent2, 0], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.geoid});
this.geoid = this.geoparent.getObjId('Intersection');
var num = this.geoid.match(/GeoIntersection_{([0-9]+)}/)[1];
this.sendInfo(board, 'start');
this.currStep = 0;
return [{
geoid: this.geoid,
name: 'i' + num,
type: 'Intersection',
parent1: this.parent1,
parent2: this.parent2
}];
} else {
this.currStep--;
return [];
}
break;
default:
return [];
break;
}
return [];
}
} // End GeoToolIntersection
{ // GeoToolNormal
/****************************************
* GeoToolNormal - Tool for creating normal.
****************************************/
var GeoToolNormal = function(geoparent){
this.type = 'Normal';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolNormal);
GeoToolLine.prototype.subtools.push('Normal');
/**
* Inherit the virtual GeoTool.
**/
GeoToolNormal.prototype = new GeoTool();
/**
* Icon for line tool. - Use the same icon as for GeoLine-object.
**/
GeoToolNormal.prototype.icon = GeoNormal.prototype.icon;
/**
* Init the GeoToolNormal. Reset the stepnumber etc.
**/
GeoToolNormal.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.line = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolNormal.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var elements = this.getElementsInCoords(board, coords);
if (elements.length === 0) {
this.currStep--;
this.sendInfo(board, 'error-' + this.currStep);
return [];
} else {
this.p1 = elements[0];
this.p1geoid = this.p1.id;
this.line = board.create('Normal', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
return [];
}
break;
case 2:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line.remove();
this.line = board.create('Normal', [this.p1, this.p2], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
this.normalgeoid = this.geoparent.getObjId('Normal');
this.result.push({type: 'Normal', name: this.line.name, geoid: this.normalgeoid, p1: this.p1geoid, p2: this.p2geoid});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.normalgeoid = this.geoparent.getObjId('Normal');
this.result.push({type: 'Normal', name: this.line.name, geoid: this.normalgeoid, p1: this.p1geoid, p2: this.p2geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolNormal
{ // GeoToolParallel
/****************************************
* GeoToolParallel - Tool for creating parallel.
****************************************/
var GeoToolParallel = function(geoparent){
this.type = 'Parallel';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolParallel);
GeoToolLine.prototype.subtools.push('Parallel');
/**
* Inherit the virtual GeoTool.
**/
GeoToolParallel.prototype = new GeoTool();
/**
* Icon for line tool. - Use the same icon as for GeoLine-object.
**/
GeoToolParallel.prototype.icon = GeoParallel.prototype.icon;
/**
* Init the GeoToolParallel. Reset the stepnumber etc.
**/
GeoToolParallel.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.line = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolParallel.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var elements = this.getLinesInCoords(board, coords);
if (elements.length === 0) {
this.currStep--;
this.sendInfo(board, 'error-' + this.currStep);
return [];
} else {
this.p1 = elements[0];
this.p1geoid = this.p1.id;
this.line = board.create('Parallel', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1});
return [];
}
break;
case 2:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line.remove();
this.line = board.create('Parallel', [this.p1, this.p2], {color: 'gray', strokeWidth: 1});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
this.normalgeoid = this.geoparent.getObjId('Normal');
this.result.push({type: 'Parallel', name: this.line.name, geoid: this.normalgeoid, p1: this.p1geoid, p2: this.p2geoid});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.parallelgeoid = this.geoparent.getObjId('Parallel');
this.result.push({type: 'Parallel', name: this.line.name, geoid: this.parallelgeoid, p1: this.p1geoid, p2: this.p2geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolParallel
{ // GeoToolTangent
/****************************************
* GeoToolTangent - Tool for creating normal.
****************************************/
var GeoToolTangent = function(geoparent){
this.type = 'Tangent';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 2;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolTangent);
GeoToolLine.prototype.subtools.push('Tangent');
/**
* Inherit the virtual GeoTool.
**/
GeoToolTangent.prototype = new GeoTool();
/**
* Icon for line tool. - Use the same icon as for GeoLine-object.
**/
GeoToolTangent.prototype.icon = GeoTangent.prototype.icon;
/**
* Init the GeoToolTangent. Reset the stepnumber etc.
**/
GeoToolTangent.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.tangent1 = null;
this.tangent2 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolTangent.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var elements = this.getElementsInCoords(board, coords);
if (elements.length === 0) {
this.currStep--;
this.sendInfo(board, 'error-' + this.currStep);
return [];
} else {
this.p1 = elements[0];
this.p1geoid = this.p1.id;
var helpline = board.create(
'Tangent',
[this.p1, 'gedithiddenmousecursor'],
{
visible: false
}
);
var int1 = board.create(
'intersection',
[this.p1, helpline, 0],
{
strokeColor: 'gray',
face: '+'
}
);
var int2 = board.create(
'intersection',
[this.p1, helpline, 1],
{
strokeColor: 'gray',
face: '+'
}
);
this.tangent1 = board.create(
'line',
[int1, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1
}
);
this.tangent2 = board.create(
'line',
[int2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1
}
);
return [];
}
break;
case 2:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create(
'Point',
[data.xcoord, data.ycoord],
{
color: 'gray',
face: 'x',
id: this.p2geoid
}
);
var helpline = board.create(
'Tangent',
[this.p1, this.p2],
{
color: 'gray',
strokeWidth: 1
}
);
var int1 = board.create(
'intersection',
[this.p1, helpline, 0],
{
strokeColor: 'gray',
face: '+'
}
);
var int2 = board.create(
'intersection',
[this.p1, helpline, 1],
{
strokeColor: 'gray',
face: '+'
}
);
var tangent1 = board.create(
'line',
[this.p2, int1],
{visible: false}
);
this.result.push({
type: 'Point',
name: this.p2.name,
geoid: this.p2geoid,
x: data.xcoord, y:
data.ycoord
});
this.tangentgeoid = this.geoparent.getObjId('Tangent');
this.result.push({
type: 'Tangent',
name: tangent1.name,
geoid: this.tangentgeoid,
p1: this.p1geoid,
p2: this.p2geoid
});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.tangentgeoid = this.geoparent.getObjId('Tangent');
var fakeline = board.create('line', [this.p2, this.p2], {visible: false});
this.result.push({
type: 'Tangent',
name: fakeline.name,
geoid: this.tangentgeoid,
p1: this.p1geoid,
p2: this.p2geoid
});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolTangent
{ // GeoToolRectangle
/****************************************
* GeoToolRrectangle - Tool for creating rectangles.
****************************************/
var GeoToolRectangle = function(geoparent){
this.type = 'Rectangle';
this.geoparent = geoparent;
this.subtool = false;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolRectangle);
//GeoToolTriangle.prototype.subtools.push('Rectangle');
/**
* Inherit the virtual GeoTool.
**/
GeoToolRectangle.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolRectangle.prototype.subtools = [];
/**
* Icon for rectangle tool. - Use the same icon as for GeoRectangle-object.
**/
GeoToolRectangle.prototype.icon = GeoRectangle.prototype.icon;
/**
* Init the GeoToolRectangle. Reset the stepnumber etc.
**/
GeoToolRectangle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.p4 = null
this.line1 = null;
this.line2 = null;
this.line3 = null;
this.line4 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolRectangle.prototype.click = function(data){
var geotool = this;
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
var helpline2 = board.create('parallel', ['gedithiddenmousecursor', this.line1], {visible: false, strokeColor: 'gray'});
var helppoint1 = board.create('intersection', [helpline1, helpline2, 0], {visible: true, face: 'x', strokeColor: 'gray'});
var helppoint2 = board.create('parallelpoint', [this.p2, this.p1, helppoint1], {visible: false, face: 'x', strokeColor: 'gray'});
this.line2 = board.create('Line', [this.p2, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [helppoint1, helppoint2], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line4 = board.create('Line', [this.p1, helppoint2], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
var helpline2 = board.create('parallel', ['gedithiddenmousecursor', this.line1], {visible: false, strokeColor: 'gray'});
var helppoint1 = board.create('intersection', [helpline1, helpline2, 0], {visible: true, face: 'x', strokeColor: 'gray'});
var helppoint2 = board.create('parallelpoint', [this.p2, this.p1, helppoint1], {visible: false, face: 'x', strokeColor: 'gray'});
this.line2 = board.create('Line', [this.p2, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [helppoint1, helppoint2], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line4 = board.create('Line', [this.p1, helppoint2], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
}
this.p3 = helppoint1;
this.p4 = helppoint2;
return [];
break;
case 3:
this.sendInfo(board, 'start');
this.p3dist = this.p3.Dist(this.p2);
if (JXG.Math.Geometry.trueAngle(this.p1, this.p2, this.p3) < 180) {
this.p3dist = -this.p3dist;
}
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
this.p3name = this.p3.name;
this.p4name = this.p4.name;
this.rectanglegeoid = this.geoparent.getObjId('Rectangle');
this.result.push({type: 'Rectangle', name: '\u25af'+this.p1.name+this.p2.name + this.p3name + this.p4name, geoid: this.rectanglegeoid, p1: this.p1geoid, p2: this.p2geoid, p3dist: this.p3dist, p3name: this.p3name, p4name: this.p4name});
this.p3.remove();
this.p4.remove();
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolRectangle
{ // GeoToolRtriangle
/****************************************
* GeoToolRtriangle - Tool for creating rectangles.
****************************************/
var GeoToolRtriangle = function(geoparent){
this.type = 'Rtriangle';
this.geoparent = geoparent;
this.subtool = true;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolRtriangle);
GeoToolTriangle.prototype.subtools.push('Rtriangle');
/**
* Inherit the virtual GeoTool.
**/
GeoToolRtriangle.prototype = new GeoTool();
/**
* Icon for rtriangle tool. - Use the same icon as for GeoRtriangle-object.
**/
GeoToolRtriangle.prototype.icon = GeoRtriangle.prototype.icon;
/**
* Init the GeoToolRtriangle. Reset the stepnumber etc.
**/
GeoToolRtriangle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.line1 = null;
this.line2 = null;
this.line3 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolRtriangle.prototype.click = function(data){
var geotool = this;
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
var helpline2 = board.create('parallel', ['gedithiddenmousecursor', this.line1], {visible: false, strokeColor: 'gray'});
var helppoint1 = board.create('intersection', [helpline1, helpline2, 0], {visible: true, face: 'x', strokeColor: 'gray'});
this.line2 = board.create('Line', [this.p2, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p1, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
var helpline2 = board.create('parallel', ['gedithiddenmousecursor', this.line1], {visible: false, strokeColor: 'gray'});
var helppoint1 = board.create('intersection', [helpline1, helpline2, 0], {visible: true, face: 'x', strokeColor: 'gray'});
this.line2 = board.create('Line', [this.p2, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.line3 = board.create('Line', [this.p1, helppoint1], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
}
this.p3 = helppoint1;
return [];
break;
case 3:
this.sendInfo(board, 'start');
this.p3dist = this.p3.Dist(this.p2);
if (JXG.Math.Geometry.trueAngle(this.p1, this.p2, this.p3) < 180) {
this.p3dist = -this.p3dist;
}
var helpline1 = board.create('normal', [this.p2, this.line1], {visible: false, strokeColor: 'gray'});
this.p3name = this.p3.name;
this.rtrianglegeoid = this.geoparent.getObjId('Rtriangle');
this.result.push({type: 'Rtriangle', name: '\u25b3'+this.p1.name+this.p2.name + this.p3name, geoid: this.rtrianglegeoid, p1: this.p1geoid, p2: this.p2geoid, p3dist: this.p3dist, p3name: this.p3name});
this.p3.remove();
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolRtriangle
{ // GeoToolAngle
/****************************************
* GeoToolAngle - Tool for creating Angles.
****************************************/
var GeoToolAngle = function(geoparent){
this.type = 'Angle';
this.geoparent = geoparent;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolAngle);
/**
* Inherit the virtual GeoTool.
**/
GeoToolAngle.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolAngle.prototype.subtools = [];
/**
* Icon for angle tool. - Use the same icon as for GeoAngle-object.
**/
GeoToolAngle.prototype.icon = GeoAngle.prototype.icon;
/**
* Init the GeoToolAngle. Reset the stepnumber etc.
**/
GeoToolAngle.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p2 = null;
this.line1 = null;
this.line2 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolAngle.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point', [data.xcoord, data.ycoord], {fillColor: 'gray', strokeColor: 'gray', face: 'x', id: this.p1geoid});
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p1.name, geoid: this.p1geoid, x: data.xcoord, y: data.ycoord});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line', [this.p1, 'gedithiddenmousecursor'], {strokeColor: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p2geoid});
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.line2 = board.create('Line', [this.p2, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line', [this.p1, this.p2], {color: 'gray', strokeWidth: 1, straightFirst: false, straightLast: false});
this.line2 = board.create('Line', [this.p2, 'gedithiddenmousecursor'], {strokeColor: 'gray', withLabel: false, strokeWidth: 1, straightFirst: false, straightLast: false});
}
return [];
break;
case 3:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p3geoid = this.geoparent.getObjId('Point');
this.p3 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p3geoid});
this.line1.remove();
this.line2.remove();
this.result.push({type: 'Point', name: this.p3.name, geoid: this.p3geoid, x: data.xcoord, y: data.ycoord});
this.geoid = this.geoparent.getObjId('Angle');
this.result.push({type: 'Angle', name: '\u2220'+this.p1.name+this.p2.name+this.p3.name, geoid: this.geoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
} else {
this.p3 = points[0];
this.p3geoid = this.p3.id;
this.geoid = this.geoparent.getObjId('Angle');
this.result.push({type: 'Angle', name: '\u2220'+this.p1.name+this.p2.name+this.p3.name, geoid: this.geoid, p1: this.p1geoid, p2: this.p2geoid, p3: this.p3geoid});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolAngle
{ // GeoToolBisector
/****************************************
* GeoToolBisector - Tool for creating Bisectors.
****************************************/
var GeoToolBisector = function(geoparent){
this.type = 'Bisector';
this.geoparent = geoparent;
this.subtool = true;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
* Register as subtool of another tool.
**/
GEditor.prototype.geotools.push(GeoToolBisector);
GeoToolLine.prototype.subtools.push('Bisector');
GeoToolAngle.prototype.subtools.push('Bisector');
/**
* Inherit the virtual GeoTool.
**/
GeoToolBisector.prototype = new GeoTool();
/**
* Icon for angle tool. - Use the same icon as for GeoAngle-object.
**/
GeoToolBisector.prototype.icon = GeoBisector.prototype.icon;
/**
* Init the GeoToolBisector. Reset the stepnumber etc.
**/
GeoToolBisector.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p2 = null;
this.line1 = null;
this.line2 = null;
this.bisector = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolBisector.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create('Point',
[data.xcoord, data.ycoord],
{
fillColor: 'gray',
strokeColor: 'gray',
face: 'x',
id: this.p1geoid
});
this.line1 = board.create('Line',
[this.p1, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
this.result.push({
type: 'Point',
name: this.p1.name,
geoid: this.p1geoid,
x: data.xcoord,
y: data.ycoord
});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create('Line',
[this.p1, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create('Point',
[data.xcoord, data.ycoord],
{
color: 'gray',
face: 'x',
id: this.p2geoid
});
this.line1.remove();
this.line1 = board.create('Line',
[this.p1, this.p2],
{
color: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
this.line2 = board.create('Line',
[this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
this.bisector = board.create('bisector',
[this.p1, this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: true,
straightLast: true
});
this.result.push({
type: 'Point',
name: this.p2.name,
geoid: this.p2geoid,
x: data.xcoord,
y: data.ycoord
});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.line1.remove();
this.line1 = board.create('Line',
[this.p1, this.p2],
{
color: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
this.line2 = board.create('Line',
[this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
});
this.bisector = board.create('bisector',
[this.p1, this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: true,
straightLast: true
});
}
return [];
break;
case 3:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p3geoid = this.geoparent.getObjId('Point');
this.p3 = board.create('Point',
[data.xcoord, data.ycoord],
{
color: 'gray',
face: 'x',
id: this.p3geoid
});
this.line1.remove();
this.line2.remove();
this.result.push({
type: 'Point',
name: this.p3.name,
geoid: this.p3geoid,
x: data.xcoord,
y: data.ycoord
});
this.geoid = this.geoparent.getObjId('Bisector');
this.result.push({type: 'Bisector',
name: this.p1.name+this.p2.name+this.p3.name,
geoid: this.geoid,
p1: this.p1geoid,
p2: this.p2geoid,
p3: this.p3geoid
});
} else {
this.p3 = points[0];
this.p3geoid = this.p3.id;
this.geoid = this.geoparent.getObjId('Bisector');
this.result.push({
type: 'Bisector',
name: this.p1.name+this.p2.name+this.p3.name,
geoid: this.geoid,
p1: this.p1geoid,
p2: this.p2geoid,
p3: this.p3geoid
});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolBisector
{ // GeoToolParallelogram
/****************************************
* GeoToolParallelogram - Tool for creating parallelograms.
****************************************/
var GeoToolParallelogram = function(geoparent){
this.type = 'Parallelogram';
this.subtool = true;
this.geoparent = geoparent;
this.steps = 3;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolParallelogram);
GeoToolRectangle.prototype.subtools.push('Parallelogram');
/**
* Inherit the virtual GeoTool.
**/
GeoToolParallelogram.prototype = new GeoTool();
/**
* Icon for parallelogram tool. - Use the same icon as for GeoParallelogram-object.
**/
GeoToolParallelogram.prototype.icon = GeoParallelogram.prototype.icon;
/**
* Init the GeoToolParallelogram. Reset the stepnumber etc.
**/
GeoToolParallelogram.prototype.init = function(){
this.currStep = 0;
this.result = [];
this.p1 = null;
this.p2 = null;
this.p3 = null;
this.p4 = null;
this.line1 = null;
this.line2 = null;
this.line3 = null;
this.line4 = null;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolParallelogram.prototype.click = function(data){
this.currStep = this.currStep + 1;
var board = data.board;
var coords = new JXG.Coords(JXG.COORDS_BY_USER, [data.xcoord, data.ycoord], board);
switch (this.currStep){
case 1:
this.sendInfo(board, this.currStep);
this.result = [];
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p1geoid = this.geoparent.getObjId('Point');
this.p1 = board.create(
'Point',
[data.xcoord, data.ycoord],
{
fillColor: 'gray',
strokeColor: 'gray',
face: 'x',
id: this.p1geoid
}
);
this.line1 = board.create(
'Line',
[this.p1, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.result.push({
type: 'Point',
name: this.p1.name,
geoid: this.p1geoid,
x: data.xcoord,
y: data.ycoord
});
return [];
} else {
this.p1 = points[0];
this.p1geoid = this.p1.id;
this.line1 = board.create(
'Line',
[this.p1, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
return [];
}
break;
case 2:
this.sendInfo(board, this.currStep);
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p2geoid = this.geoparent.getObjId('Point');
this.p2 = board.create(
'Point',
[data.xcoord, data.ycoord],
{
color: 'gray',
face: 'x',
id: this.p2geoid
}
);
this.p4 = board.create(
'parallelpoint',
[this.p2, this.p1, 'gedithiddenmousecursor'],
{
color: 'gray',
face: 'x',
id: 'gedittempparallelpoint'
}
);
this.line1.remove();
this.line1 = board.create(
'Line',
[this.p1, this.p2],
{
color: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line2 = board.create(
'Line',
[this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line3 = board.create(
'Line',
['gedithiddenmousecursor', 'gedittempparallelpoint'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line4 = board.create(
'Line',
['gedittempparallelpoint', this.p1],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.result.push({type: 'Point', name: this.p2.name, geoid: this.p2geoid, x: data.xcoord, y: data.ycoord});
} else {
this.p2 = points[0];
this.p2geoid = this.p2.id;
this.p4 = board.create(
'parallelpoint',
[this.p2, this.p1, 'gedithiddenmousecursor'],
{
color: 'gray',
face: 'x',
id: 'gedittempparallelpoint'
}
);
this.line1.remove();
this.line1 = board.create(
'Line',
[this.p1, this.p2],
{
color: 'gray',
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line2 = board.create(
'Line',
[this.p2, 'gedithiddenmousecursor'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line3 = board.create(
'Line',
['gedithiddenmousecursor', 'gedittempparallelpoint'],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
this.line4 = board.create(
'Line',
['gedittempparallelpoint', this.p1],
{
strokeColor: 'gray',
withLabel: false,
strokeWidth: 1,
straightFirst: false,
straightLast: false
}
);
}
return [];
break;
case 3:
this.sendInfo(board, 'start');
var points = this.getPointsInCoords(board, coords);
if (points.length === 0) {
this.p3geoid = this.geoparent.getObjId('Point');
this.p3 = board.create('Point', [data.xcoord, data.ycoord], {color: 'gray', face: 'x', id: this.p3geoid});
this.result.push({type: 'Point', name: this.p3.name, geoid: this.p3geoid, x: data.xcoord, y: data.ycoord});
this.parallgeoid = this.geoparent.getObjId('Parallelogram');
this.result.push({
type: 'Parallelogram',
name: '\u25b1'+this.p1.name+this.p2.name+this.p3.name+this.p4.name,
geoid: this.parallgeoid,
p1: this.p1geoid,
p2: this.p2geoid,
p3: this.p3geoid,
p4name: this.p4.name
});
} else {
this.p3 = points[0];
this.p3geoid = this.p3.id;
this.parallgeoid = this.geoparent.getObjId('Parallelogram');
this.result.push({
type: 'Parallelogram',
name: '\u25b1'+this.p1.name+this.p2.name+this.p3.name+this.p4.name,
geoid: this.parallgeoid,
p1: this.p1geoid,
p2: this.p2geoid,
p3: this.p3geoid,
p4name: this.p4.name
});
}
this.currStep = 0;
break;
default:
this.result = [];
}
return this.result;
}
} // End GeoToolParallelogram
{ // GeoToolLabel
/****************************************
* GeoToolLabel - Tool for creating text labels.
****************************************/
var GeoToolLabel = function(geoparent){
this.type = 'Label';
this.geoparent = geoparent;
this.steps = 1;
}
/**
* Register the tool to the GEditor.
**/
GEditor.prototype.geotools.push(GeoToolLabel);
/**
* Inherit the virtual GeoTool.
**/
GeoToolLabel.prototype = new GeoTool();
/**
* Subtool list.
**/
GeoToolLabel.prototype.subtools = [];
/**
* Icon for label tool. - Use the same icon as for GeoLabel-object.
**/
GeoToolLabel.prototype.icon = GeoLabel.prototype.icon;
/**
* Init the GeoToolLabel. Reset the stepnumber etc.
**/
GeoToolLabel.prototype.init = function(){
this.step = 0;
}
/**
* Actions for clicking the board. Return data for the new object.
**/
GeoToolLabel.prototype.click = function(data){
this.currStep = 0;
this.geoid = this.geoparent.getObjId('Label');
return [{
type: 'Label',
id: this.geoid,
value: 'Text',
x: Math.round(data.xcoord * 100)/100,
y: Math.round(data.ycoord * 100)/100
}];
}
} // End GeoToolLabel
} // End Geotools
{ // GeoWidgets
// Place for widgettypes.
GEditor.prototype.widgets = {};
/*********************************************
* Virtual class for Widget for collecting data for geometric property.
*/
var GeoWidget = function(place, options, data){}
/**
* Localize strings
*/
GeoWidget.prototype.localize = function(str, lang){
return this.localizer.localize(str, lang);
}
/**
* Use template and replace variables in it.
*/
GeoWidget.prototype.useTemplate = function(tname, data){
var str = this.templates[tname];
for (var key in data) {
var rex = RegExp('{{{'+key+'}}}', 'g');
str = str.replace(rex, data[key]);
}
return str;
}
/**
* Html-templates
*/
GeoWidget.prototype.templates = {
}
/*********************************************
* GeoWidgetLabel for static label.
*/
var GeoWidgetLabel = function(place, options, data){
this.type = 'Label';
this.place = place;
this.key = options.key || '';
this.value = options.value || '';
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Label'] = GeoWidgetLabel;
/**
* Inherit GeoWidget
*/
GeoWidgetLabel.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetLabel.prototype.init = function(){
var html = this.value;
this.place.html(html);
}
/*********************************************
* GeoWidgetText for asking textdata.
*/
var GeoWidgetText = function(place, options, data){
this.type = 'Text';
this.place = place;
this.key = options.key || '';
this.value = options.value || '';
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Text'] = GeoWidgetText;
/**
* Inherit GeoWidget
*/
GeoWidgetText.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetText.prototype.init = function(){
var html = '<input type="text" value="' + this.value + '" data-geoattribute="'+this.key+'" />';
this.place.html(html);
}
/*********************************************
* GeoWidgetColor for asking color in rgb.
*/
var GeoWidgetColor = function(place, options, data){
this.type = 'Color';
this.place = place;
this.key = options.key || '';
this.value = options.value || '';
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Color'] = GeoWidgetColor;
/**
* Inherit GeoWidget
*/
GeoWidgetColor.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetColor.prototype.init = function(){
var html = '<input type="text" value="' + this.value + '" data-geoattribute="'+this.key+'" />';
this.place.html(html);
if (typeof(jQuery.fn.colpicker) === 'function') {
this.place.find('input[type="text"]').colpicker({showInput: true, hiddable: true});
}
}
/*********************************************
* GeoWidgetTextbox for asking textdata.
*/
var GeoWidgetTextbox = function(place, options, data){
this.type = 'Textbox';
this.place = place;
this.key = options.key || '';
this.value = options.value || '';
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Textbox'] = GeoWidgetTextbox;
/**
* Inherit GeoWidget
*/
GeoWidgetTextbox.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetTextbox.prototype.init = function(){
var html = '<textarea type="text" data-geoattribute="'+this.key+'">' + this.value + '</textarea>';
this.place.html(html);
}
/*********************************************
* GeoWidgetCheckbox for asking yes/no -data.
*/
var GeoWidgetCheckbox = function(place, options, data){
this.type = 'Checkbox';
this.place = place;
this.key = options.key || '';
this.value = options.value || false;
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Checkbox'] = GeoWidgetCheckbox;
/**
* Inherit GeoWidget
*/
GeoWidgetCheckbox.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetCheckbox.prototype.init = function(){
var html = '<input type="checkbox" ' + (this.value ? 'checked="checked"' : '') + '" data-geoattribute="'+this.key+'" />';
this.place.html(html);
}
/*********************************************
* GeoWidgetSelect for asking one-from-multiple -data.
*/
var GeoWidgetSelect = function(place, options, data){
this.type = 'Select';
this.place = place;
this.key = options.key || '';
this.option = options.data || data || [];
this.selected = options.value;
this.localizer = new Localizer(place.closest('[lang]').attr('lang'));
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Select'] = GeoWidgetSelect;
/**
* Inherit GeoWidget
*/
GeoWidgetSelect.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetSelect.prototype.init = function(){
var html = ['<select data-geoattribute="'+this.key+'" >'];
for (var i = 0; i < this.option.length; i++) {
var option = '<option value="' + this.option[i].id + '" ' + (this.selected && this.selected.toString() === this.option[i].id.toString() ? 'selected="selected"' : '') + '>' + this.localize(this.option[i].name) + '</option>';
html.push(option);
}
html.push('</select>');
this.place.html(html.join('\n'));
}
/*********************************************
* GeoWidgetBoxarea for asking textdata.
*/
var GeoWidgetBoxarea = function(place, options, data){
this.type = 'Boxarea';
this.place = place;
this.key = options.key || [0,1,2,3];
this.value = options.value || ['','','',''];
}
/**
* Register this widget.
*/
GEditor.prototype.widgets['Boxarea'] = GeoWidgetBoxarea;
/**
* Inherit GeoWidget
*/
GeoWidgetBoxarea.prototype = new GeoWidget();
/**
* Get the html for the widget.
*/
GeoWidgetBoxarea.prototype.init = function(){
var html = '<table><tbody><tr><td></td><td colspan="2"><span class="geoProperty"><input type="text" value="' + this.value[0] + '" size="2" data-geoattribute="'+this.key[0]+'" /></span></td><td></td></tr><tr><td colspan="2"><span class="geoProperty"><input type="text" value="' + this.value[1] + '" size="2" data-geoattribute="'+this.key[1]+'" /></span></td><td colspan="2"><span class="geoProperty"><input type="text" value="' + this.value[2] + '" size="2" data-geoattribute="'+this.key[2]+'" /></span></td></tr><tr><td></td><td colspan="2"><span class="geoProperty"><input type="text" value="' + this.value[3] + '" size="2" data-geoattribute="'+this.key[3]+'" /></span></td><td></td></tr></tbody></table>';
this.place.replaceWith(html);
}
} // End GeoWidgets
{ // GeoDialogs
/********************************
* Base class for dialogs.
*/
var GeoDialog = function(place, options){
options = $.extend({
title: '',
text: '',
buttons: [
{
text: 'OK',
event: '',
data: {}
}
]
}, options);
this.place = place;
this.titletext = options.title;
this.text = options.text;
this.buttons = options.buttons;
}
GeoDialog.prototype.show = function(){
if ($('head style#geodialogstyle').length === 0) {
$('head').append('<style id="geodialogstyle" type="text/css">'+this.templates.style+'</style>');
}
this.wrapper = this.place.append(this.templates.dialog).find('.gedit-dialog-wrapper').last();
this.dialog = this.wrapper.children().eq(0);
this.title = this.dialog.find('.gedit-dialog-title');
this.content = this.dialog.find('.gedit-dialog-content');
this.buttonbar = this.dialog.find('.gedit-dialog-buttonbar');
this.addButtons();
this.initHandlers();
this.title.html(this.titletext);
this.content.html(this.text);
}
GeoDialog.prototype.remove = function(){
this.wrapper.remove();
}
GeoDialog.prototype.initHandlers = function(){
var gdialog = this;
for (var i = 0; i < this.buttons.length; i++) {
this.dialog.delegate('.gedit-dialog-button[data-action="'+i+'"]', 'click', function(e){
var action = $(this).attr('data-action');
var button = gdialog.buttons[action];
if (button.event) {
gdialog.place.trigger(button.event, [button.data]);
}
gdialog.remove();
});
}
}
GeoDialog.prototype.addButtons = function(){
for (var i = 0; i < this.buttons.length; i++) {
var button = this.templates.button.replace(/{{button}}/g, this.buttons[i].text). replace(/{{buttonid}}/g, i);
this.buttonbar.append(button);
}
}
GeoDialog.prototype.templates = {
dialog: [
'<div class="gedit-dialog-wrapper">',
'<div class="gedit-dialog">',
'<div class="gedit-dialog-title"></div>',
'<div class="gedit-dialog-content"></div>',
'<div class="gedit-dialog-buttonbar"></div>',
'</div>',
'</div>'
].join('\n'),
button: '<div class="gedit-dialog-button" data-action="{{buttonid}}">{{button}}</div>',
style: [
'.gedit-dialog-wrapper {position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.2);}',
'.gedit-dialog {position: absolute; bottom: 20px; right: 20px; width: 300px; border: 1px solid black; border-radius: 8px; box-shadow: 4px 4px 8px rgba(0,0,0,0.5);}',
'.gedit-dialog .gedit-dialog-title {font-weight: bold; font-size: 150%; padding: 0.2em 0.5em; height: 1.2em; overflow-hidden;}',
'.gedit-dialog {background: rgb(238,238,238);',
'background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1)));',
'background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 );}",
'.gedit-dialog .gedit-dialog-content { min-height: 100px; padding: 0 0.5em;}',
'.gedit-dialog .gedit-dialog-buttonbar {text-align: right; padding: 0.2em 1em;}',
'.gedit-dialog .gedit-dialog-buttonbar .gedit-dialog-button {display: inline-block; cursor: pointer; background-color: #a00; text-align: center; border: 1px solid black; border-radius: 4px; box-shadow: -1px -1px 1px rgba(0,0,0,0.5), inset 1p 1px 1px rgba(255,255,255,0.7), inset -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.7); color: white; font-weight: bold; text-shadow: 1px 1px 1px rgba(255,255,255,0.7), -1px -1px 1px rgba(0,0,0,0.5); padding: 0.1em 0.8em; margin: 0 0.2em;}'
].join('\n')
}
/******************************
* GeoAlert - custom alert for GEditor.
*/
var GeoAlert = function(place, options){
this.place = place;
this.titletext = options && options.title || '';
this.text = options && options.text || '';
this.callbacks = {
'Ok': options.callbacks && options.callbacks['Ok'] || function(){}
}
this.buttons = ['Ok'];
}
GeoAlert.prototype = new GeoDialog();
/******************************
* GeoConfirm - custom confirm for GEditor.
*/
var GeoConfirm = function(place, options){
this.place = place;
this.titletext = options && options.title || '';
this.text = options && options.text || '';
this.callbacks = {
'Ok': options.callbacks && options.callbacks['Ok'] || function(){},
'Cancel': options.callbacks && options.callbacks['Cancel'] || function(){}
}
this.buttons = ['Cancel','Ok'];
}
GeoConfirm.prototype = new GeoDialog();
} // End GeoDialogs
})(jQuery);
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.geoedit2 = {
/******************************
* Show geoeditor2
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var geoname = '';
var editable = false;
var isauthor = false;
if (params.length > 0){
geoname = params[0];
}
if (params.length > 1){
editable = (params[1] === 'author' || params[1] === 'edit');
isauthor = params[1] === 'author';
}
var grapheditordiv = '{{geoeditor{\n}}}';
wikify(grapheditordiv, place, null, tiddler);
var geoeditors = (tiddler ? DataTiddler.getData(tiddler, 'Geoeditors', {}): {});
if (geoname !== ''){
var editor = jQuery.extend(true, {}, geoeditors[geoname]);
}
editor.editable = editable;
jQuery(place).find('.geoeditor').attr('geoeditor',params[0]).geditor(editor);
if (editable && params[1] !== 'author'){
jQuery(place).find('.geoeditor').bind('geoeditor_changed', function(e){
var geoeditors = DataTiddler.getData(tiddler, 'Geoeditors', {});
var geodata = jQuery(this).geditor('getdata');
geoeditors[geoname] = geodata;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(tiddler, 'Geoeditors', geoeditors, {});
config.options.chkAutoSave = autosavestatus;
});
}
}
}
}
//}}}
//{{{
/*
* OnOff-button
* OnOff-look for checkbox. jQuery-plugin
*
* Petri Salmela (pesalmel@abo.fi)
* Petri Sallasmaa (pekasa@utu.fi)
*
* License: AGPL
*/
(function($){
// jQuery plugin
$.fn.emathonoff = function(options){
// Test for options
if (typeof(options) !== 'object'){
options = {};
// Placeholder variable for returning value.
}
// Extend default settings with user given options.
var settings = $.extend(true, {
texts: ['on','off'],
coloron: 'blue',
coloroff: 'gray'
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
if ($(this).is('input[type="checkbox"]')){
// Create new OnOff object.
var onoff = new OnOff(this, settings);
// Init the examplepicture
onoff.init();
}
});
}
var OnOff = function(place, settings){
this.checkbox = $(place);
this.texts = settings.texts;
this.coloron = settings.coloron;
this.coloroff = settings.coloroff;
}
OnOff.prototype.init = function(){
this.checkbox.hide();
this.onoff = $('<div class="emathonoff"></div>');
this.checkbox.after(this.onoff);
this.onoff.html('<div class="emathonoff-on"><span>'+this.texts[0]+'</span></div><div class="emathonoff-block emathonoff-grayroundgrad"><span> </span></div><div class="emathonoff-off"><span>'+this.texts[1]+'</span></div>');
if ($('head style#emathonoffcss').length < 1){
$('head').append('<style id="emathonoffcss" type="text/css">'+this.strings.css+'</style>');
}
this.on = this.onoff.find('.emathonoff-on');
this.off = this.onoff.find('.emathonoff-off');
this.block = this.onoff.find('.emathonoff-block');
this.width = Math.max(this.on.width(), this.off.width());
this.on.width(this.width);
this.off.width(this.width);
this.on.css('margin-left',(this.checkbox.is(':checked') ? 0: -1*this.width));
this.off.css('margin-right', (this.checkbox.is(':checked') ? -1*this.width : 0));
this.block.css({'width': '0.7em'});
this.on.addClass('emathonoff-'+this.coloron+'grad');
this.off.addClass('emathonoff-'+this.coloroff+'grad');
if (this.checkbox.is(':checked')){
this.onoff.addClass('ison');
}
this.initEvents();
}
OnOff.prototype.initEvents = function(){
var widget = this;
this.onoff.click(function(){
if (widget.checkbox.is(':checked')){
widget.onoff.removeClass('ison');
widget.on.animate({'margin-left': -1*widget.width}, 'fast');
widget.off.animate({'margin-right': 0}, 'fast');
widget.block.animate({'margin-left': 0, 'margin-right': '-0.3em'}, 'fast');
widget.checkbox.click();
} else {
widget.onoff.addClass('ison');
widget.off.animate({'margin-right': -1*widget.width}, 'fast');
widget.on.animate({'margin-left': 0}, 'fast');
widget.block.animate({'margin-right': 0, 'margin-left': '-0.3em'}, 'fast');
widget.checkbox.click();
}
});
}
OnOff.prototype.strings = {
css: [
'.emathonoff {border: 1px solid #555; border-radius: 0.6em; background-color: black; margin: 0.5em 1em; padding: 0; position: relative; overflow: hidden; cursor: pointer; vertical-align: middle;}',
'.emathonoff, .emathonoff .emathonoff-on, .emathonoff .emathonoff-block, .emathonoff .emathonoff-off {display: inline-block; position: relative;}',
'.emathonoff .emathonoff-on, .emathonoff .emathonoff-off { margin: -1px 0 -2px 0; padding: 0; text-align: center; z-index:1; overflow: hidden; box-shadow: inset 2px 2px 2px rgba(0,0,0,0.5);}',
'.emathonoff .emathonoff-on span, .emathonoff .emathonoff-off span, .emathonoff .emathonoff-block span {margin: 0; padding: 0.3em 0.5em; display: inline-block;}',
'.emathonoff .emathonoff-on span {padding: 0.3em 0.8em 0.3em 0.5em;}',
'.emathonoff .emathonoff-off span {padding: 0.3em 0.5em 0.3em 0.8em;}',
'.emathonoff .emathonoff-block {margin: -1px -0.3em -2px 0; z-index: 2; border: 1px solid white; border-radius: 0.8em; background-color: #444; overflow: hidden; box-shadow: 2px 2px 2px rgba(0,0,0,0.5);}',
'.emathonoff.ison .emathonoff-block {margin-right: 0; margin-left: -0.3em;}',
'.emathonoff .emathonoff-on {background-color: blue;}',
'.emathonoff .emathonoff-off {background-color: #aaa; color: black;}',
'.emathonoff-bluegrad {color: black!important; font-weight: bold; text-shadow: 0 0 1px white; background: #05abe0;',
'background: -moz-linear-gradient(top, #05abe0 0%, #53cbf1 60%, #87e0fd 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#05abe0), color-stop(60%,#53cbf1), color-stop(100%,#87e0fd));',
'background: -webkit-linear-gradient(top, #05abe0 0%,#53cbf1 60%,#87e0fd 100%);',
'background: -o-linear-gradient(top, #05abe0 0%,#53cbf1 60%,#87e0fd 100%);',
'background: -ms-linear-gradient(top, #05abe0 0%,#53cbf1 60%,#87e0fd 100%);',
'background: linear-gradient(to bottom, #05abe0 0%,#53cbf1 60%,#87e0fd 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#05abe0\', endColorstr=\'#87e0fd\',GradientType=0 );}',
'.emathonoff-graygrad {color: black!important; font-weight: bold; text-shadow: 0 0 1px white; background: #e2e2e2;',
'background: -moz-linear-gradient(top, #e2e2e2 0%, #dbdbdb 50%, #d1d1d1 51%, #fefefe 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#e2e2e2), color-stop(50%,#dbdbdb), color-stop(51%,#d1d1d1), color-stop(100%,#fefefe));',
'background: -webkit-linear-gradient(top, #e2e2e2 0%,#dbdbdb 50%,#d1d1d1 51%,#fefefe 100%);',
'background: -o-linear-gradient(top, #e2e2e2 0%,#dbdbdb 50%,#d1d1d1 51%,#fefefe 100%);',
'background: -ms-linear-gradient(top, #e2e2e2 0%,#dbdbdb 50%,#d1d1d1 51%,#fefefe 100%);',
'background: linear-gradient(to bottom, #e2e2e2 0%,#dbdbdb 50%,#d1d1d1 51%,#fefefe 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#e2e2e2\', endColorstr=\'#fefefe\',GradientType=0 );}',
'.emathonoff-grayroundgrad {background: rgb(181,189,200);',
'background: -moz-radial-gradient(center, ellipse cover, rgba(181,189,200,1) 0%, rgba(130,140,149,1) 36%, rgba(40,52,59,1) 100%);',
'background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(181,189,200,1)), color-stop(36%,rgba(130,140,149,1)), color-stop(100%,rgba(40,52,59,1)));',
'background: -webkit-radial-gradient(center, ellipse cover, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%);',
'background: -o-radial-gradient(center, ellipse cover, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%);',
'background: -ms-radial-gradient(center, ellipse cover, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%);',
'background: radial-gradient(ellipse at center, rgba(181,189,200,1) 0%,rgba(130,140,149,1) 36%,rgba(40,52,59,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#b5bdc8\', endColorstr=\'#28343b\',GradientType=1 );}',
'.emathonoff-redgrad {color: white!important; font-weight: bold; text-shadow: 0 0 1px black; background: rgba(207,4,4,1);',
'background: -moz-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(207,4,4,1)), color-stop(100%,rgba(255,48,25,1)));',
'background: -webkit-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%);',
'background: -o-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%);',
'background: -ms-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%);',
'background: linear-gradient(to bottom, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#cf0404\', endColorstr=\'#ff3019\',GradientType=0 );}',
'.emathonoff-greengrad {color: white!important; font-weight: bold; text-shadow: 0 0 1px black; background: rgba(117,137,12,1);',
'background: -moz-linear-gradient(top, rgba(117,137,12,1) 0%, rgba(164,179,87,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(117,137,12,1)), color-stop(100%,rgba(164,179,87,1)));',
'background: -webkit-linear-gradient(top, rgba(117,137,12,1) 0%,rgba(164,179,87,1) 100%);',
'background: -o-linear-gradient(top, rgba(117,137,12,1) 0%,rgba(164,179,87,1) 100%);',
'background: -ms-linear-gradient(top, rgba(117,137,12,1) 0%,rgba(164,179,87,1) 100%);',
'background: linear-gradient(to bottom, rgba(117,137,12,1) 0%,rgba(164,179,87,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#75890c\', endColorstr=\'#a4b357\',GradientType=0 );}',
'.emathonoff-yellowgrad {color: black!important; font-weight: bold; text-shadow: 0 0 1px white; background: rgb(241,218,54);',
'background: -moz-linear-gradient(top, rgba(241,218,54,1) 0%, rgba(254,252,234,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(241,218,54,1)), color-stop(100%,rgba(254,252,234,1)));',
'background: -webkit-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%);',
'background: -o-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%);',
'background: -ms-linear-gradient(top, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%);',
'background: linear-gradient(to bottom, rgba(241,218,54,1) 0%,rgba(254,252,234,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#f1da36\', endColorstr=\'#fefcea\',GradientType=0 );}'
].join(' ')
}
})(jQuery);
//}}}
//{{{
/*********************************************************
* jquery.emathquiz.js
* jQuery-plugin for drawing functions
* Petri Salmela
* Petri Sallasmaa
* 30.12.2012
* License: LGPL 2.0 or later
********************************************************/
var testilogit = {};
(function($){
/**
* emathquiz
* @param options
*/
$.fn.emathquiz = function(options){
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on emathquiz' );
return this;
}
}
var methods = {
init: function( options ){
var settings = $.extend({
autonext: true,
score: 0,
total: 0
}, options);
return this.each(function(){
var emquiz = new EmathQuiz(this, settings);
emquiz.init();
});
},
score: function(){
// Return the scores as {correct: <number>, total: <number>}
return this.eq(0).data('emathquiz');
}
};
var EmathQuiz = function(place, settings){
// Create EmathQuiz-object. Put empty html-elements in the place and
// find some elements that are needed later.
testilogit.emq = this;
this.place = $(place);
this.settings = settings;
this.lang = this.settings.lang || this.place.attr('lang') || this.place.parents('[lang]').eq(0).attr('lang') || 'en';
this.dict = {};
// Keep the score
this.totalquestions = this.settings.total;
this.correctanswers = this.settings.score;
var htmlcontent = '<div class="emathquizwrapper"><div class="emquiz-title"></div>'
+'<div class="emquiz-picarea"></div><div class="emquiz-question">'
+'<div class="emquiz-question-textarea"></div>'
+'<div class="emquiz-question-answersarea"></div>'
+'<div class="emquiz-feedbackarea"></div>'
+'<div class="emquiz-controlarea"></div></div></div>';
this.place.html(htmlcontent);
this.wrapper = this.place.find('.emathquizwrapper');
this.wrapper.addClass('emquiz-gradblue');
if (this.settings.overlay){
// If we use quiz as overlay instead of inline.
this.wrapper.addClass('emquizoverlay')
}
// Place for title
this.titlearea = this.place.find('.emquiz-title');
// Place for picture
this.picarea = this.place.find('.emquiz-picarea');
this.quizid = -1;
while ($('#emquiz-picarea-'+(++this.quizid)).length > 0){};
this.picarea.attr('id','emquiz-picarea-'+this.quizid);
// Place for question text
this.qtextarea = this.place.find('.emquiz-question-textarea');
// Place for answer
this.qanswersarea = this.place.find('.emquiz-question-answersarea');
// Place for feedback
this.feedbackarea = this.place.find('.emquiz-feedbackarea');
// Place for controls like "answer" and "next" buttons and "scores"
this.controlarea = this.place.find('.emquiz-controlarea');
this.controlarea.html('<div class="emquiz-resultarea">'+this.correctanswers+'/'+this.totalquestions+'</div>'
+'<a href="javascript:;" class="emquiz-answerbutton emquiz-button">OK</a>'
+'<a href="javascript:;" class="emquiz-nextbutton emquiz-button">»</a>');
this.resultarea = this.controlarea.find('.emquiz-resultarea');
// Put css in use.
$('head style#emathquizcss').remove();
$('head').append('<style id="emathquizcss" type="text/css">'+this.strings.css+'</style>')
}
EmathQuiz.prototype.init = function(){
// Init the quiz from options given.
var emquiz = this;
// Put the title on its place
this.title = this.settings.title || '';
this.titlearea.html('<h1>'+this.title+'</h1>');
// Check the type of given action function: 'function', 'string' or 'array' of functions.
if (typeof(this.settings.func) === 'function'){
// Function is given as function
this.nextquestion = this.settings.func;
} else if (typeof(this.settings.func) === 'string'){
// Function is given as a string of javascript code
try {
this.nextquestion = new Function(this.settings.func);
} catch (err){
$.error('Emathquiz: error in nextquestion function.');
}
} else if (typeof(this.settings.func) === 'object' && typeof(this.settings.func.length) === 'number'){
// Functions are given as an array of functions. Either strings of functions.
var nfuncs = [];
for (var i = 0; i < this.settings.func.length; i++){
if (typeof(this.settings.func[i]) === 'function'){
nfuncs.push(this.settings.func[i]);
} else if (typeof(this.settings.func[i]) === 'string'){
try {
nfuncs.push(new Function(this.settings.func[i]));
} catch (err){
$.error('Emathquiz: error in nextquestion function.');
}
}
}
this.settings.func = nfuncs;
this.nextquestion = function(){
return emquiz.settings.func[Math.floor(Math.random()*emquiz.settings.func.length)].call(this);
}
} else {
// No function was given. Use default example question.
this.nextquestion = this.defaultQuestion;
}
// Init some events. ('Answer' and 'Next' buttons)
this.initEvents();
// Start the next (first) question.
this.update();
}
EmathQuiz.prototype.initEvents = function(){
// Init some events. ('Answer' and 'Next' buttons)
var emquiz = this;
this.controlarea.find('a.emquiz-answerbutton').click(function(){
emquiz.checkAnswer();
});
this.controlarea.find('a.emquiz-nextbutton').click(function(e){
e.stopPropagation();
e.preventDefault();
if (emquiz.nexttimeout){
clearTimeout(emquiz.nexttimeout);
}
emquiz.update();
return false;
})
}
EmathQuiz.prototype.update = function(){
// Start next round by generating next question and using it.
var emquiz = this;
this.wrapper.removeClass('emquiz-correctanswer');
this.controlarea.find('a.emquiz-answerbutton').show()
.end().find('a.emquiz-nextbutton').hide();
// Get data for next question.
this.question = this.nextquestion();
// Set the style
this.question.qstyle = this.question.qstyle || 'default';
this.wrapper.attr('qstyle', this.question.qstyle).attr('qtype', this.question.qtype);
// Clear the feedback
this.feedbackarea.empty().removeClass('emquiz-feedback-correct emquiz-feedback-wrong');
// Show the question. Show math with mathquill.
this.qtextarea.html(this.question.qtext.replace(/\\\(/g, '<span class="mathquill-embedded-latex">').replace(/\\\)/g, '</span>'))
.find('.mathquill-embedded-latex').mathquill('embedded-latex');
// Init the answering section according to the type of question (multichoice, shortanswer)
var answers = '';
switch (this.question.qtype){
case 'multichoice':
// Show multichoice answers
answers = '<ul class="emquiz-multichoice">';
for (var i = 0; i < this.question.qanswers.length; i++){
answers += '<li><input type="radio" name="emquiz-'+this.quizid +'-multichoice" id="emquiz-'
+this.quizid+'-multichoice-'+i+'" value="'+i+'" />';
answers +='<label for="emquiz-'+this.quizid+'-multichoice-'+i+'">'
+this.question.qanswers[i]
.replace(/\\\(/, '<span class="mathquill-embedded-latex">')
.replace(/\\\)/, '</span>')+'</label></li>';
}
answers += '</ul>'
break;
case 'shortanswer':
// Show the answering field for short answer.
answers = '<div class="emquiz-shortanswer">';
answers += '<span class="emquiz-shortanswer-useranswer mathquill-editable"></span>';
answers += '</div>';
break;
case 'image':
// Show (don't show) the answering widgets for image quiz.
default:
break;
}
// Show math with mathquill
this.qanswersarea.html(answers).find('.mathquill-editable').mathquill('editable').focus().keydown(function(e){
if (e.which === 13){
emquiz.controlarea.find('a.emquiz-answerbutton').click();
}
}).end().find('.mathquill-embedded-latex').mathquill();
if (this.settings.autonext){
this.qanswersarea.find('input[type="radio"]').change(function(e){
if (emquiz.answertimeout){
clearTimeout(emquiz.answertimeout);
}
emquiz.answertimeout = setTimeout(function(){
emquiz.controlarea.find('a.emquiz-answerbutton').click();
emquiz.nexttimeout = setTimeout(function(){emquiz.controlarea.find('a.emquiz-nextbutton').click();}, 5000);
}, 1000);
});
}
// Show or hide picarea.
if (this.question.haspicture){
this.wrapper.addClass('emquiz-haspicture');
} else {
this.wrapper.removeClass('emquiz-haspicture');
}
// Draw the picture with jsxgraph+jessiescript, if this.question.jessie exists.
if (this.question.jessie){
this.picarea.empty();
this.construction = [];
var jxgoptions = JXG.Options;
// Some default settings for picture.
JXG.Options = JXG.deepCopy(JXG.Options, {
showNavigation: false,
text: {
fontSize: 20
},
angle: {
radius: 1.1,
label: {
strokeColor: '#ff0000'
},
orthoSensitivity: 0.5
},
point: {
fixed: true,
size: 1.3
},
glider: {
fixed: false,
color: '#f00',
size: 5,
strokeColor: 'black',
strokeWidth: 3,
face: 'x'
},
line: {
strokeWidth: 3,
shadow: true
}
});
// Init the board
if (this.board){
JXG.JSXGraph.freeBoard(this.board);
}
this.board = JXG.JSXGraph.initBoard("emquiz-picarea-"+this.quizid, {
boundingbox: this.question.jessiebb || [0,10,10,0],
keepaspectratio: true,
grid: true,
showCopyright: false,
showNavigation: false,
pan: false,
zoom: false
});
this.construction = [];
this.board.suspendUpdate();
this.construction['question'] = this.board.construct(this.question.jessie);
if (this.question.lblabels){
for (var i = 0; i < this.question.lblabels.length; i++){
this.board.elementsByName[this.question.lblabels[i]].label.content.setProperty({offset: [-20,-20]});
}
}
if (this.question.ltlabels){
for (var i = 0; i < this.question.ltlabels.length; i++){
this.board.elementsByName[this.question.ltlabels[i]].label.content.setProperty({offset: [-20,20]});
}
}
if (this.question.rblabels){
for (var i = 0; i < this.question.rblabels.length; i++){
this.board.elementsByName[this.question.rblabels[i]].label.content.setProperty({offset: [10,-20]});
}
}
if (this.question.rtlabels){
for (var i = 0; i < this.question.rtlabels.length; i++){
this.board.elementsByName[this.question.rtlabels[i]].label.content.setProperty({offset: [10,20]});
}
}
if (this.question.jessiestyles && this.question.jessiestyles['question']){
this.setJsxProperty('question');
}
if (this.question.jessielabels && this.question.jessielabels['question']){
this.setJsxLabels('question');
}
this.board.unsuspendUpdate();
testilogit.board = this.board;
testilogit.construction = this.construction;
JXG.Options = jxgoptions;
}
}
EmathQuiz.prototype.setJsxProperty = function(elementset, ruleset){
/**
* @param String elementset - the name of construction set of jsxelements
* @param String ruleset - the name of set of style rules for jsxelements. If null, then use elementset.
*/
ruleset = ruleset || elementset;
for (var elems in this.question.jessiestyles[elementset]){
if (typeof(this.construction[elementset][elems].length) === 'undefined'){
this.construction[elementset][elems].setProperty(this.question.jessiestyles[ruleset][elems]);
} else {
for (var i = 0, length = this.construction[elementset][elems].length; i < length; i++){
this.construction[elementset][elems][i].setProperty(this.question.jessiestyles[ruleset][elems]);
}
}
}
}
EmathQuiz.prototype.setJsxLabels = function(elementset, labelset){
/**
* @param String elementset - the name of construction set of jsxelements
* @param String labelset - the name of set of labels for jsxelements. If null, then use elementset.
*/
labelset = labelset || elementset;
var labels = this.question.jessielabels[elementset];
var construction = this.construction[elementset];
for (var elem in labels){
if (construction[elem] && typeof(construction[elem].length) === 'undefined'){
this.construction[elementset][elem].label.content.setText(labels[elem](construction));
}
}
}
EmathQuiz.prototype.localize = function(text){
var result;
if (this.dict[text]){
if (this.dict[text][this.lang]){
result = this.dict[text][this.lang];
}
result = result || this.dict[text]['en'];
}
result = result || text;
return result;
}
EmathQuiz.prototype.defaultQuestion = function(){
// "Dummy" default function for questions, if real question function is not given.
// Returns randomly either multichoice question or short answer question.
var questions = [
{
qtype: 'multichoice',
qtext: '<p>Mikä on vastaus?</p>',
qanswers: [
'Eka \\(\\beta\\)',
'Toka \\(\\frac{1}{2}\\)',
'Kolmas',
'Neljäs: Tähän oikein pitkä vastaus. Vaikka jotain lorem ipsumia.'
],
correct: '2',
jessie: 'A(1,2); B(9,3); C(3,8); [A B] nolabel; [BC] nolabel; [C A] nolabel; 45\u00b0=<(B,A,C)',
lblabels: ['A']
},
{
qtype: 'shortanswer',
qtext: '<p>Kuinka paljon?</p>',
correct: [2.5, 3.5],
check: function(answer, corrects){
var result = false;
var replacers = [
[/\\frac{([^{}]+)}{([^{}]+)}/ig, '(($1)/($2))'],
[/\\sqrt{([^{}]+)}/ig, 'Math.sqrt($1)'],
[/\\cdot/ig, '*'],
[/\\left\(/ig, '('],
[/\\right\)/ig, ')'],
[/((?:[0-9]+)|(?:\([^\(\)]\)))\^((?:[0-9])|(?:{[0-9]+}))/ig, 'pow($1, $2)'],
[/,/ig, '.']
];
var oldanswer = '';
while (answer !== oldanswer){
oldanswer = answer;
for (var i = 0; i < replacers.length; i++){
answer = answer.replace(replacers[i][0], replacers[i][1]);
}
}
try {
var corrfunc = new Function('return ('+ answer +');');
for (var i = 0; i < corrects.length; i++){
result = result || (corrects[i] == corrfunc());
}
} catch (err){
}
return result;
},
jessie: 'A(1,2); B(9,3); C(3,8); [A B] nolabel; [BC] nolabel; [C A] nolabel; 45\u00b0=<(B,A,C)',
lblabels: ['A']
}
]
return questions[Math.floor(Math.random()*questions.length)];
}
EmathQuiz.prototype.checkAnswer = function(){
// Check the answer and show the correct one before continuing
// to the next one.
this.wrapper.addClass('emquiz-correctanswer');
this.controlarea.find('a.emquiz-answerbutton').hide()
.end().find('a.emquiz-nextbutton').show();
var correct = false;
switch (this.question.qtype){
case 'multichoice':
this.answer = parseInt(this.qanswersarea.find(':checked').val());
this.qanswersarea.find('li').eq(parseInt(this.question.correct)).addClass('emquiz-multichoice-correct');
this.qanswersarea.find('li').eq(parseInt(this.answer)).addClass('emquiz-multichoice-useranswer');
correct = (this.question.correct === this.answer);
break;
case 'shortanswer':
this.answer = this.qanswersarea.find('.emquiz-shortanswer-useranswer').mathquill('latex') || '';
var useranswer = this.qanswersarea.find('.emquiz-shortanswer-useranswer');
useranswer.mathquill('revert').html(this.answer).mathquill('embedded-latex');
if (typeof(this.question.check) === 'function'){
correct = this.question.check(this.answer, this.question.correct);
} else {
for (var i = 0; i < this.question.correct.length; i++){
correct = correct || (this.answer == this.question.correct[i]);
}
}
if (correct){
this.qanswersarea.find('.emquiz-shortanswer-useranswer').addClass('emquiz-shortanswer-correct');
} else {
useranswer.after('<div class="emquiz-shortanswer-correct">'+this.question.correct[0]+'</div>');
}
break;
case 'image':
this.answer = this.question.getAnswer(this.board);
correct = this.question.check(this.answer, this.question.correct);
if (!(correct && this.question.jessiehidecorrect)){
this.board.suspendUpdate();
this.construction['correct'] = this.board.construct(this.question.jessiecorrect);
if (this.question.jessiestyles){
this.setJsxProperty('question', 'questionafter');
this.setJsxProperty('correct');
}
this.board.unsuspendUpdate();
}
break
default:
this.answer = '';
break;
}
this.totalquestions++;
if (correct){
this.correctanswers++;
}
if (this.question.feedback){
this.feedbackarea.addClass(correct ? 'emquiz-feedback-correct' : 'emquiz-feedback-wrong')
.html(this.question.feedback
.replace(/\\\(/g, '<span class="mathquill-embedded-latex">')
.replace(/\\\)/g, '</span>')
).find('.mathquill-embedded-latex').mathquill('embedded-latex');
}
this.resultarea.html(this.correctanswers +'/'+ this.totalquestions);
this.controlarea.find('a.emquiz-nextbutton').focus();
this.place.data('emathquiz', {correct: this.correctanswers, total: this.totalquestions});
this.place.trigger('changed');
}
EmathQuiz.prototype.strings = {
// CSS style rules.
css: [
'.emathquizwrapper {border: 1px solid #777; border-radius: 1em; box-shadow: 5px 5px 5px rgba(0,0,0,0.5), inset 2px 2px 4px rgba(255,255,255,0.8), inset -2px -2px 4px black; min-height: 5em; margin: 1em; padding: 0.5em;}',
'.emathquizwrapper.emquizoverlay {position: fixed; top: 5em; width: 90%; max-width: 1000px; margin: 0 auto; left: 5%; right: 5%;}',
'.emathquizwrapper:after {content: " "; clear: both; display: block;}',
'.emquiz-title h1 {color: #005; text-align: center; border: none; margin: 0.2em 0.5em; text-shadow: 1px 1px 2px white, -1px -1px 1px black, 1px 1px 2px white;}',
'.emquiz-picarea {border: 1px solid #777; border-radius: 5px; background: white; box-shadow: inset 5px 5px 5px rgba(0,0,0,0.2); margin: 5px; display: none;}',
'[qstyle="default"] .emquiz-picarea {float: left; width: 300px; height: 300px;}',
'[qstyle="bigpic"] .emquiz-picarea {height: 300px;}',
'[qstyle="widepic"] .emquiz-picarea {height: 150px;}',
'.emquiz-haspicture .emquiz-picarea {display: block;}',
'.emquiz-question {margin: 6px 5px 5px 5px; padding-top: 5px;}',
'.emquiz-haspicture[qstyle="widepic"] .emquiz-question, .emquiz-haspicture[qstyle="bigpic"] .emquiz-question',
'{margin: 6px 5px 5px 5px; padding-top: 5px;}',
'.emquiz-haspicture .emquiz-question {margin: 6px 5px 5px 315px;}',
'.emquiz-question-textarea, .emquiz-question-answersarea, .emquiz-feedbackarea {border: 1px solid #777; border-radius: 5px; background-color: rgba(255,255,255,0.8); padding: 0 1em; margin: 0 0 1em 0; min-height: 2em; box-shadow: inset 4px 4px 6px rgba(0,0,0,0.3);}',
'[qtype="image"] .emquiz-question-answersarea {display: none;}',
'.emquiz-feedbackarea {visibility: hidden;}',
'.emquiz-feedbackarea.emquiz-feedback-correct {background-color: rgb(248,255,232); visibility: visible;}',
'.emquiz-feedbackarea.emquiz-feedback-wrong {background-color: rgb(254,187,187); visibility: visible;}',
'.emquiz-feedbackarea p.corrfeedback, .emquiz-feedbackarea p.wrongfeedback {display: none;}',
'.emquiz-feedbackarea.emquiz-feedback-correct p.corrfeedback, .emquiz-feedbackarea.emquiz-feedback-wrong p.wrongfeedback {display: block;}',
'ul.emquiz-multichoice {list-style: none; padding-left: 1em;}',
'ul.emquiz-multichoice li {min-height: 2em; padding: 0.5em 0; margin: 0.5em 0;}',
'ul.emquiz-multichoice li label {padding-left: 2em; vertical-align: base-line; cursor: pointer;}',
'.emquiz-correctanswer ul.emquiz-multichoice input[type="radio"] {display: none;}',
'.emquiz-correctanswer ul.emquiz-multichoice li.emquiz-multichoice-correct, .emquiz-correctanswer .emquiz-shortanswer-correct, .emquiz-correctanswer ul.emquiz-multichoice li.emquiz-multichoice-correct.emquiz-multichoice-useranswer',
'{border-radius: 10px; border: 2px solid #a9c314; box-shadow: 0 0 2px white;',
'background: rgb(248,255,232);',
'background: -moz-linear-gradient(top, rgba(248,255,232,1) 0%, rgba(227,245,171,1) 33%, rgba(183,223,45,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(248,255,232,1)), color-stop(33%,rgba(227,245,171,1)), color-stop(100%,rgba(183,223,45,1)));',
'background: -webkit-linear-gradient(top, rgba(248,255,232,1) 0%,rgba(227,245,171,1) 33%,rgba(183,223,45,1) 100%);',
'background: -o-linear-gradient(top, rgba(248,255,232,1) 0%,rgba(227,245,171,1) 33%,rgba(183,223,45,1) 100%);',
'background: -ms-linear-gradient(top, rgba(248,255,232,1) 0%,rgba(227,245,171,1) 33%,rgba(183,223,45,1) 100%);',
'background: linear-gradient(to bottom, rgba(248,255,232,1) 0%,rgba(227,245,171,1) 33%,rgba(183,223,45,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#f8ffe8\', endColorstr=\'#b7df2d\',GradientType=0 );}',
'.emquiz-correctanswer ul.emquiz-multichoice li.emquiz-multichoice-useranswer {border-radius: 10px; border: 2px solid #e81818; box-shadow: 0 0 2px white;',
'background: rgb(254,187,187);',
'background: -moz-linear-gradient(top, rgba(254,187,187,1) 0%, rgba(254,144,144,1) 45%, rgba(255,92,92,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,187,187,1)), color-stop(45%,rgba(254,144,144,1)), color-stop(100%,rgba(255,92,92,1)));',
'background: -webkit-linear-gradient(top, rgba(254,187,187,1) 0%,rgba(254,144,144,1) 45%,rgba(255,92,92,1) 100%);',
'background: -o-linear-gradient(top, rgba(254,187,187,1) 0%,rgba(254,144,144,1) 45%,rgba(255,92,92,1) 100%);',
'background: -ms-linear-gradient(top, rgba(254,187,187,1) 0%,rgba(254,144,144,1) 45%,rgba(255,92,92,1) 100%);',
'background: linear-gradient(to bottom, rgba(254,187,187,1) 0%,rgba(254,144,144,1) 45%,rgba(255,92,92,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#febbbb\', endColorstr=\'#ff5c5c\',GradientType=0 );}',
'.emquiz-shortanswer {padding: 1em; min-height: 2em;}',
'.emquiz-shortanswer .emquiz-shortanswer-correct {display: block; padding: 0.3em 1em; margin: 0.3em 0;}',
'.emquiz-shortanswer .emquiz-shortanswer-useranswer {display: block; margin: 0.3em; background-color: white; padding: 0.2em;}',
'.emquiz-controlarea {text-align: right; clear: both;}',
'.emquiz-resultarea {float: left; background-color: rgba(255,255,255,0.8); border: 1px solid #777; border-radius: 5px; min-width: 8em; padding: 0.5em; text-align: center; box-shadow: inset 4px 4px 6px rgba(0,0,0,0.3);}',
'.emquiz-button, .emathquizwrapper a.emquiz-button:hover {display: inline-block; padding: 0.5em 1em; border-radius: 0.3em; text-decoration: none; margin: 0 0.5em; min-width: 6em;',
'border: 1px solid black; text-align: center; color: black; font-weight: bold; text-shadow: 1px 1px 1px white;',
'background: rgb(254,252,234);',
'background: -moz-linear-gradient(top, rgba(254,252,234,1) 0%, rgba(241,218,54,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,252,234,1)), color-stop(100%,rgba(241,218,54,1)));',
'background: -webkit-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%);',
'background: -o-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%);',
'background: -ms-linear-gradient(top, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%);',
'background: linear-gradient(to bottom, rgba(254,252,234,1) 0%,rgba(241,218,54,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#fefcea\', endColorstr=\'#f1da36\',GradientType=0 );}',
'.emquiz-button:hover {box-shadow: 0 0 3px white; color: black;}',
'.emquiz-nextbutton {display: none;}',
'.emquiz-correctanswer .emquiz-nextbutton {display: inline-block;}',
'.emquiz-correctanswer .emquiz-answerbutton {display: none;}',
'.emquiz-gradgray {background: rgb(179,190,173);',
'background: -moz-linear-gradient(top, rgba(179,190,173,1) 0%, rgba(223,229,215,1) 60%, rgba(252,255,244,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(179,190,173,1)), color-stop(60%,rgba(223,229,215,1)), color-stop(100%,rgba(252,255,244,1)));',
'background: -webkit-linear-gradient(top, rgba(179,190,173,1) 0%,rgba(223,229,215,1) 60%,rgba(252,255,244,1) 100%);',
'background: -o-linear-gradient(top, rgba(179,190,173,1) 0%,rgba(223,229,215,1) 60%,rgba(252,255,244,1) 100%);',
'background: -ms-linear-gradient(top, rgba(179,190,173,1) 0%,rgba(223,229,215,1) 60%,rgba(252,255,244,1) 100%);',
'background: linear-gradient(to bottom, rgba(179,190,173,1) 0%,rgba(223,229,215,1) 60%,rgba(252,255,244,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#b3bead\', endColorstr=\'#fcfff4\',GradientType=0 );}',
'.emquiz-gradblue {background: rgb(135,224,253);,',
'background: -moz-linear-gradient(top, rgba(135,224,253,1) 0%, rgba(83,203,241,1) 40%, rgba(5,171,224,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(135,224,253,1)), color-stop(40%,rgba(83,203,241,1)), color-stop(100%,rgba(5,171,224,1)));',
'background: -webkit-linear-gradient(top, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%);',
'background: -o-linear-gradient(top, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%);',
'background: -ms-linear-gradient(top, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%);',
'background: linear-gradient(to bottom, rgba(135,224,253,1) 0%,rgba(83,203,241,1) 40%,rgba(5,171,224,1) 100%);',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#87e0fd\', endColorstr=\'#05abe0\',GradientType=0 );}'
].join('\n')
}
})(jQuery)
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.emathquiz = {
/******************************
* Show emathquiz
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
/**
* emathquiz
* @param params[0] - overlaymode [[modal##button title]] / [[inline]]
* @param param[1] - init score and total as: [[score##total]] or as empty [[]] (or [[0##0]])
* @param param[2-(n-1)] - functions to use in format:
* triangleanglesum##multichoice (for function in tiddler part 'emquiz_triangleanglesum##multichoice')
*/
if (params.length < 3){
wikify('Missing funcquiz.', place, null, tiddler);
return false;
}
var bookpage = {'pageOne': 0, 'pageTwo': 1}[jQuery(place).parents('.bookpage').attr('id')];
var bookid = EbookPages[bookpage].ebook.bookid;
var overlayparams = params.shift() || '';
overlayparams = overlayparams.split('##');
var overlaymode = (overlayparams[0] === 'modal');
var title = overlayparams[1];
var booklang = overlayparams[2] || EbookPages[bookpage].currentlang;
var initparams = params.shift() || '';
initparams = initparams.split('##');
var initscore = parseInt(initparams[0]) || 0;
var inittotal = parseInt(initparams[1]) || 0;
var funcs = [];
for (var i = 0, length = params.length; i < length; i++){
var functext = store.getTiddlerText(bookid+'_emquiz_'+params[i]) || store.getTiddlerText('emquiz_'+params[i]) || '';
if (functext){
funcs.push(functext);
}
}
var html = '<html><div class="emathquiz-place" lang="'+booklang+'"><a href="javascript:;" class="emathquiz-button">'+title
+'</a><div class="emathquiz"></div></div></html>';
if (overlaymode){
wikify(html, place);
var emqbutton = jQuery(place).find('a.emathquiz-button').last();
emqbutton.button({
icons: {
primary: "em-icon-quiz"
}
});
emqbutton.click(function(){
var backdiv = jQuery(this).next();
backdiv.html('<div class="emq-wrapper"></div><a href="javascript:;">x</a>');
backdiv.css({
'position': 'fixed',
'top': '0',
'right': '0',
'bottom': '0',
'left': '0',
'background-color': 'rgba(255,255,255,0.9)',
'z-index': '201'
});
var closebutton = backdiv.find('a');
closebutton.click(function(){
backdiv.empty().css('position', 'static');
}).css({
'display': 'inline-block',
'position': 'absolute',
'top': '20px',
'right': '20px',
'height': '1.5em',
'width': '1.5em',
'border-radius': '0.4em',
'border': '2px solid black',
'background': '#f00',
'color': 'white',
'text-align': 'center',
'vertical-align': 'middle',
'font-weight': 'bold',
'box-shadow': 'inset 2px 2px 3px rgba(255,255,255,0.5), inset -2px -2px 3px rgba(0,0,0,0.5)'
});
var content = backdiv.find('.emq-wrapper');
content.emathquiz({title: title, func: funcs, overlay: overlaymode, lang: booklang});
});
} else {
wikify('<html><div class="emathquiz-place" lang="'+booklang+'"></div></html>', place);
jQuery(place).find('.emathquiz-place').last()
.emathquiz({
title: title,
func: funcs,
overlay: overlaymode,
score: initscore,
total: inittotal,
lang: booklang
});
}
return true;
}
}
}
//}}}
<<emathtocapp>>
<data>{"ebookapps":[{"name":"EmathTocapp","content":"emathtocapp","icon":"calculator.png","openpage":"EmathTocapp","showclosebutton":true,"iconsvg":"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"40\" height=\"40\" viewbox=\"0 0 30 30\" class=\"mini-icon mini-icon-toc\"><path style=\"stroke: none;\" d=\"M4 4 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 10 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M10 16 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M10 22 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 28 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z\" /></svg>"}]}</data>
/***
|''Name:''|emathtocapp.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|TOC-app for for E-math ebook|
|''Version:''|1.1|
|''Date:''|October 1, 2013|
|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/copyleft/lesser.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20131031.1154 ''fix/add'' ''Version 1.1''
* ul data-emchaplist attribute fixed
* ul levelattribute added
* toc number and toc toctitle wrapped with own span
<<<
<<<
20131031.0941 ''start''
<<<
!!!!!Code
***/
//{{{
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.emathtocapp = {
/*********************************
* Show the toc of ebook
*********************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var num = 0;
while (jQuery('#emtocapp-'+num).length > 0){num++};
var wrapperName = 'emtocapp-'+num;
var html = '<div id="'+wrapperName+'"></div>';
var options = {};
options.tocdata = EbookPages[0].ebook.tocObject();
options.lang = EbookPages[0].currentlang;
jQuery(place).append(html).find('#'+wrapperName).emathtocapp(options);
}
}
}
(function($){
/**
* emathtocapp
* @param options
*/
$.fn.emathtocapp = function(options){
if (methods[options]){
return methods[options].apply( this, Array.prototype.slice.call( arguments, 1));
} else if (typeof(options) === 'object' || !options) {
return methods.init.apply(this, arguments);
} else {
$.error( 'Method ' + method + ' does not exist on emathtocapp' );
return this;
}
}
var methods = {
init: function( options ){
var settings = $.extend({
}, options);
return this.each(function(){
var emtoc = new EmathTocapp(this, settings);
//testilogit.emslidecrtr = emslidecrtr;
emtoc.init();
});
}
};
var EmathTocapp = function(place, settings){
// Construct the EmathTocapp
settings = $.extend(true, {
tocdata: {
bookid: "0000",
title: "empty book",
alttitles: [],
curriculum: "xx",
lang: "en",
altlangs: [],
author: [],
secondaryauthor: [],
updateurl: "",
style: "",
frontpage: {
title: "empty book",
alttitles: {},
types: [],
chapid: "front",
content: "",
chapters: []
}
},
lang: "en"
}, settings);
this.place = $(place);
this.place.addClass('emtocapp-wrapper');
if (typeof(settings.tocdata) === 'string') {
try {
this.toc = JSON.parse(settings.tocdata);
} catch (ex) {
this.toc = {};
}
} else {
this.toc = settings.tocdata;
}
this.lang = settings.lang;
}
EmathTocapp.prototype.init = function(){
this.addStyles();
this.view();
this.initHandlers();
}
EmathTocapp.prototype.view = function(){
// Show the toc
this.place.html(EmathTocapp.strings.template);
this.header = this.place.find('.emtoc-header');
this.content = this.place.find('.emtoc-content');
var title = this.toc.alttitles && this.toc.alttitles[this.lang] || this.toc.title;
this.header.find('h1.emtoc-title').html(title);
//this.header.find('.emtoc-headdata').html();
var html = '<ul class="emtoc-chapterlist" toclevel = "0" data-emchaplist="'+this.toc.frontpage.chapid+'">\n' + this.getTochtml(0) + '</ul>\n';
this.content.html(html);
}
EmathTocapp.prototype.getTochtml = function(level, prefix, chapter){
// return the html of toc of subchapter
if (typeof(prefix) !== 'object' || typeof(prefix.length) !== 'number') {
prefix = [];
}
if (typeof(chapter) === 'undefined') {
chapter = this.toc.frontpage;
}
var hassubchaps = chapter.chapters.length > 0;
var showhide = (hassubchaps ? '<span class="emtoc-closethis">'+EmathTocapp.icons.minusclose+'</span><span class="emtoc-openthis">'+EmathTocapp.icons.plusopen+'</span>' : '');
var classes = ['emtoc-item'];
if (level > 1) {
classes.push('emtoc-hiddensubs');
}
var title = chapter.alttitles && chapter.alttitles[this.lang] || chapter.title;
var html = '<li class="'+classes.join(' ')+'" data-emchapid="'+chapter.chapid+'" data-emtoclevel="'+level+'">'+showhide+'<a href="javascript:;"><span class="emtocnro">'+ prefix.join('.') + '</span> <span class="emtoctitle">' + title+'</span></a>\n';
if(hassubchaps){
html += '<ul toclevel = "'+(level + 1)+'" class="emtoc-chapterlist" data-emchaplist="'+chapter.chapid+'">\n';
for (var i = 0; i < chapter.chapters.length; ++i){
var pref = [].concat(prefix, [''+(i+1)]);
html += this.getTochtml(level + 1, pref, chapter.chapters[i]);
}
html += '</ul>\n';
}
html += '</li>\n';
return html;
}
EmathTocapp.prototype.initHandlers = function(){
// init handlers
var tocapp = this;
this.place.delegate('li.emtoc-item a', 'click', function(event){
event.preventDefault();
var chapid = $(this).parent('li[data-emchapid]').attr('data-emchapid')
EbookPages[0].setPage(chapid);
}).delegate('li.emtoc-item span.emtoc-openthis', 'click', function(event){
$(this).parent('li.emtoc-item').eq(0).removeClass('emtoc-hiddensubs');
}).delegate('li.emtoc-item span.emtoc-closethis', 'click', function(event){
$(this).parent('li.emtoc-item').eq(0).addClass('emtoc-hiddensubs');
}).delegate('input.emtoc-searchbox', 'keyup', function(event){
var search = $(this).val();
tocapp.search(search);
}).delegate('.emtoc-search .emtoc-removesearchbutton', 'click', function(event){
tocapp.place.find('input.emtoc-searchbox').val('').focus();
tocapp.search('');
}).delegate('.emtoc-buttonbar .emtoc-foldbutton', 'click', function(event){
var action = $(this).attr('data-emtocbutton');
var opendepth = {closeall: 0, opensome: 1, openall: 2}[action];
tocapp.content.find('li.emtoc-item').removeClass('emtoc-hiddensubs');
tocapp.content.find('li.emtoc-item[data-emtoclevel="'+opendepth+'"] li.emtoc-item').addClass('emtoc-hiddensubs');
});
}
EmathTocapp.prototype.search = function(search){
// Search strings and show results.
if (search === '') {
this.content.removeClass('searching');
this.content.find('li').removeClass('searchresult');
} else {
var rex = new RegExp(search, 'i');
this.content.addClass('searching');
this.content.find('li').removeClass('searchresult');
var allstrings = this.content.find('li.emtoc-item a');
allstrings.each(function(){
var aelem = $(this);
var text = aelem.text();
if (text.match(rex)) {
var parent = aelem.parent('li.emtoc-item');
parent.addClass('searchresult');
}
});
}
}
EmathTocapp.prototype.addStyles = function(){
// Add some styles for tocapp
$('head style#emtocstyle').remove();
$('head').append('<style type="text/css" id="emtocstyle">\n'+EmathTocapp.strings.css+'\n</style>')
}
EmathTocapp.icons = {
search: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 20 20" class="mini-icon-search mini-icon"><path style="stroke: none;" d="M2 9 a6 6 0 0 0 12 0 a6 6 0 0 0 -12 0z m2 0 a4 4 0 0 1 8 0 a4 4 0 0 1 -8 0z m9 3.5 l4 4 l-2 2 l-4 -4z" /></svg>',
cross: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-cross"><path style="stroke: none;" d="M1 15 m3 -6 l4 -4 l6 6 l6 -6 l4 4 l-6 6 l6 6 l-4 4 l-6 -6 l-6 6 l-4 -4 l6 -6 z" /></svg>',
closeall: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-toc-closeall"><path style="stroke: none;" d="M4 4 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 10 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 16 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 22 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M4 28 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z" /></svg>',
opensome: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-toc-opensome"><path style="stroke: none;" d="M4 4 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M10 10 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l13 0 l0 4 l-13 0z M10 16 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l13 0 l0 4 l-13 0z M10 22 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l13 0 l0 4 l-13 0z M4 28 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z" /></svg>',
openall: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20" viewbox="0 0 30 30" class="mini-icon mini-icon-toc-openall"><path style="stroke: none;" d="M4 4 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M10 10 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l15 0 l0 4 l-15 0z M16 16 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l7 0 l0 4 l-7 0z M16 22 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l7 0 l0 4 l-7 0z M16 28 a2 2 0 0 0 4 0 a2 2 0 0 0 -4 0z m6 -2 l7 0 l0 4 l-7 0z" /></svg>',
plusopen: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" viewbox="0 0 30 30" class="mini-icon mini-icon-plusopen"> <path style="stroke: none;" d="M2 8 a6 6 0 0 1 6 -6 l14 0 a6 6 0 0 1 6 6 l0 14 a6 6 0 0 1 -6 6 l-14 0 a6 6 0 0 1 -6 -6z m2 0 l0 14 a4 4 0 0 0 4 4 l14 0 a4 4 0 0 0 4 -4 l0 -14 a4 4 0 0 0 -4 -4 l-14 0 a4 4 0 0 0 -4 4z M13 7 l4 0 l0 6 l6 0 l0 4 l-6 0 l0 6 l-4 0 l0 -6 l-6 0 l0 -4 l6 0z" /></svg>',
minusclose: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="13" height="13" viewbox="0 0 30 30" class="mini-icon mini-icon-minusclose"> <path style="stroke: none;" d="M2 8 a6 6 0 0 1 6 -6 l14 0 a6 6 0 0 1 6 6 l0 14 a6 6 0 0 1 -6 6 l-14 0 a6 6 0 0 1 -6 -6z m2 0 l0 14 a4 4 0 0 0 4 4 l14 0 a4 4 0 0 0 4 -4 l0 -14 a4 4 0 0 0 -4 -4 l-14 0 a4 4 0 0 0 -4 4z M7 13 l16 0 l0 4 l-16 0 l0 -4z" /></svg>'
}
EmathTocapp.strings = {
template: [
'<div class="emtoc-header">',
' <h1 class="emtoc-title"></h1>',
' <div class="emtoc-headbar">',
' <div class="emtoc-buttonbar">',
' <span class="emtoc-button emtoc-foldbutton" data-emtocbutton="closeall">'+EmathTocapp.icons.closeall+'</span>',
' <span class="emtoc-button emtoc-foldbutton" data-emtocbutton="opensome">'+EmathTocapp.icons.opensome+'</span>',
' <span class="emtoc-button emtoc-foldbutton" data-emtocbutton="openall">'+EmathTocapp.icons.openall+'</span>',
' </div>',
' <div class="emtoc-search">'+EmathTocapp.icons.search+'<input class="emtoc-searchbox" type="text" /><span class="emtoc-removesearchbutton">'+EmathTocapp.icons.cross+'</span></div>',
' <div class="emtoc-headdata"></div>',
' </div>',
'</div>',
'<div class="emtoc-content">',
'</div>'
].join('\n'),
css: [
'#contentWrapper[pageopen="EmathTocapp"] #pageTwoWrapper {overflow-y: scroll;}',
'.emtocapp-wrapper {border: 1px solid #999; background-color: white; margin: 0 1em; position: relative;}',
'.emtocapp-wrapper .emtoc-header {margin-top: 0.5em; margin-bottom: 0.5em;}',
'.emtocapp-wrapper h1.emtoc-title {font-size: 120%; margin: 0; padding: 0 0.5em; border: none;}',
'.emtocapp-wrapper .emtoc-headbar {padding: 0.2em; color: black; border-top: 1px solid #aaa; border-bottom: 1px solid #666;',
'background: rgb(238,238,238);',
'background: -moz-linear-gradient(top, rgba(238,238,238,1) 0%, rgba(204,204,204,1) 100%);',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(238,238,238,1)), color-stop(100%,rgba(204,204,204,1)));',
'background: -webkit-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -o-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: -ms-linear-gradient(top, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
'background: linear-gradient(to bottom, rgba(238,238,238,1) 0%,rgba(204,204,204,1) 100%);',
"filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 );}",
'.emtocapp-wrapper .emtoc-buttonbar {display: inline-block; float: left;}',
'.emtocapp-wrapper .emtoc-buttonbar .emtoc-button {display: inline-block; text-align: center; padding: 2px; border-radius: 3px; cursor: pointer; vertical-align: middle; width: 24px; height: 24px;}',
'.emtocapp-wrapper .emtoc-buttonbar .emtoc-button:hover {box-shadow: -1px -1px 1px rgba(0,0,0,0.5), inset 1px 1px 1px rgba(255,255,255,0.5), inset -1px -1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5);}',
'.emtocapp-wrapper .emtoc-buttonbar .emtoc-button:active {box-shadow: -1px -1px 1px rgba(0,0,0,0.5), inset -1px -1px 1px rgba(255,255,255,0.5), inset 1px 1px 1px rgba(0,0,0,0.5), 1px 1px 1px rgba(255,255,255,0.5);}',
'.emtocapp-wrapper .emtoc-search {float: right; margin-top: 2px; display: inline-block; text-align: left; border: 1px solid #777; box-shadow: inset 1px 1px 1px rgba(0,0,0,0.5), inset -1px -1px 1px rgba(0,0,0,0.1); border-radius: 5px; background-color: #fafafa;}',
'.emtocapp-wrapper .emtoc-search .mini-icon {display: inline-block; vertical-align: middle;}',
'.emtocapp-wrapper .emtoc-search .emtoc-removesearchbutton {display: inline-block; vertical-align: middle; margin: 0; padding: 0; cursor: pointer;}',
'.emtocapp-wrapper .emtoc-search input {border: none; background-color: transparent; display: inline-block; width: 12em; margin: 0; padding: 0.1em 0 0.1em 0.5em; vertical-align: middle;}',
'.emtocapp-wrapper .emtoc-headdata {margin: 0; padding: 0 0.8em;}',
'.emtocapp-wrapper .emtoc-headbar:after {content: ""; display: block; clear: both;}',
'.emtocapp-wrapper .emtoc-content {padding: 0.5em 1em;}',
'ul.emtoc-chapterlist {list-style: none; margin: 0; padding: 0;}',
'li.emtoc-item {clear: both;}',
'li.emtoc-item[data-emtoclevel="0"] > .emtoc-openthis, li.emtoc-item[data-emtoclevel="0"] > .emtoc-closethis {display: none}',
'li.emtoc-item[data-emtoclevel="1"] {margin-top: 0.5em; margin-bottom: 0.5em;}',
'li.emtoc-item[data-emtoclevel="1"] > a {font-weight: bold;}',
'ul.emtoc-chapterlist ul.emtoc-chapterlist {margin-left: 1.2em;}',
'li.emtoc-item.emtoc-hiddensubs > ul.emtoc-chapterlist {display: none;}',
'li.emtoc-item .emtoc-openthis, li.emtoc-item .emtoc-closethis {display: inline-block; padding: 0; margin: 0; margin-right: 0.5em; text-align: center; cursor: pointer; vertical-align: middle; float: left;}',
'li.emtoc-item .emtoc-openthis {display: none;}',
'li.emtoc-item.emtoc-hiddensubs > .emtoc-closethis {display: none;}',
'li.emtoc-item.emtoc-hiddensubs > .emtoc-openthis {display: inline-block;}',
'li.emtoc-item a {display: block; margin-left: 1.2em;}',
'.emtoc-content.searching li.emtoc-item.emtoc-hiddensubs ul.emtoc-chapterlist {display: block;}',
'.emtoc-content.searching li.emtoc-item .emtoc-openthis, .emtoc-content.searching li.emtoc-item .emtoc-closethis {display: none}',
'.emtoc-content.searching li.emtoc-item:not(.searchresult) > a {display: none;}',
'.emtoc-content.searching li.emtoc-item.searchresult {}'
].join('\n')
}
})(jQuery);
//}}}
!angletype_image
//{{{
/** Make an angle of given type: image **/
this.dict = {
'angletypes': {
'en': ['zero angle','acute angle','right angle','obtuse angle','straight angle','concave angle','reflex angle','full angle'],
'fi': ['nollakulma','terävä kulma','suora kulma','tylppä kulma','oikokulma','kovera kulma','kupera kulma','täysi kulma'],
'sv': ['nollvinkel','vass vinkel','rät vinkel','trubbig vinkel','rak vinkel','konvex vinkel','konkav vinkel','full vinkel'],
'et': ['zero angle','acute angle','right angle','obtuse angle','straight angle','concave angle','reflex angle','full angle']
},
'qtext': {
'en': '<p>Move the points so that the angle \\(\\alpha\\) is <strong>%1</strong>.</p>',
'fi': '<p>Siirrä kuvion pisteitä niin, että kulma \\(\\alpha\\) on <strong>%1</strong>.</p>',
'sv': '<p>Flytta punkterna i bilden, så att du får en <strong>%1</strong>.</p>',
'et': '<p>Move the points so that the angle \\(\\alpha\\) is <strong>%1</strong>.</p>'
},
'correct': {
'en': 'Correct!',
'fi': 'Oikein!',
'sv': 'Rätt svar!',
'et': 'Correct!'
},
'wrong': {
'en': 'Wrong!<br />See the model image.',
'fi': 'Väärin!<br />Katso mallikuviota.',
'sv': 'Fel!<br />Titta på exempelbilden bredvid.',
'et': 'Wrong!<br />See the model image.'
}
}
var angletypes = this.localize('angletypes');
var angles = [
[0],
[30, 46, 69, 82],
[90],
[100, 122, 147, 172],
[180],
[30, 46, 69, 82, 90, 100, 122, 147, 172],
[194, 230, 263, 301, 343],
[360]
];
var apoints = [[6,2],[8,3],[8,5],[8,8]];
var cpoints = [[4,2],[2,3],[2,5],[4,8]];
var apoint = apoints[Math.floor(Math.random()*apoints.length)];
var cpoint = cpoints[Math.floor(Math.random()*cpoints.length)];
var angtypeindex = Math.floor(Math.random()*angletypes.length);
var angletype = angletypes[angtypeindex];
var exampleangle = angles[angtypeindex][Math.floor(Math.random()*angles[angtypeindex].length)];
var result = {
qtype: 'image',
qstyle: 'default',
qtext: this.localize('qtext').replace(/%1/g, angletype),
haspicture: true,
feedback: '<p class="corrfeedback">'+this.localize('correct')+'</p><p class="wrongfeedback">'+this.localize('wrong')+'</p>',
jessiebb: [0, 10, 10, 0],
jessie: 'A('+apoint[0]+','+apoint[1]+') nolabel; B(5,5) nolabel; C('+cpoint[0]+','+cpoint[1]+') nolabel; [AB] nolabel; [BC] nolabel; alpha=<(A,B,C);',
jessiecorrect: 'D(3,2) invisible; E(2,2) nolabel; F('+(2+Math.cos(exampleangle * Math.PI / 180))+', '+(2+Math.sin(exampleangle * Math.PI / 180))+') invisible; [DE] nolabel; [EF] nolabel; beta=<(D,E,F) nolabel;',
jessiehidecorrect: true,
jessiestyles: {
question: {
'lines': {
'strokeColor': 'blue'
},
'points': {
'fixed': false
}
},
questionafter: {
'P': {
'fixed': true
}
},
correct: {
'lines': {
'strokeColor': 'green',
'shadow': false
},
'points': {
'fixed': true,
'color': 'green'
},
'angles': {
'radius': 0.4
}
}
},
correct: [angtypeindex],
getAnswer: function(board){
return board.elementsByName['α'];
},
check: function(answer, correct){
var angle = answer;
var points = [angle.point2, angle.point1, angle.point3];
var size = Math.round(JXG.Math.Geometry.trueAngle(points[0], points[1], points[2]));
var iscorrect = false;
switch (correct[0]) {
case 0:
iscorrect = (size === 0);
break;
case 1:
iscorrect = (0 < size && size < 90);
break;
case 2:
iscorrect = (size === 90);
break;
case 3:
iscorrect = (90 < size && size < 180);
break;
case 4:
iscorrect = (179 <= size && size <= 181);
break;
case 5:
iscorrect = (0 < size && size < 180);
break;
case 6:
iscorrect = (size > 180 && size < 360);
break;
case 7:
iscorrect = (size >= 359 || size === 0);
break;
default:
iscorrect = false;
break;
}
return iscorrect;
}
}
return result;
//}}}
!complement_multichoice
/*{{{*/
/** sum of complementary angles: multichoice **/
this.dict = {
'qtext': {
'en': '<p>A right angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>',
'fi': '<p>Suora kulma on jaettu kahteen pienempään kulmaan. Mikä on kulman \\(\\alpha\\) arvo asteina?</p>',
'sv': '<p>En rät vinkel är indelad i två mindre vinklar. Hur stor är vinkeln \\(\\alpha\\) (i grader)?</p>',
'et': '<p>A right angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'multichoice',
qtext: this.localize('qtext'),
lblabels: [],
haspicture: true,
jessie: 'A(1,9) invisible; B(1,1) invisible; C(9,1) invisible; [AB]; [BC]; '
}
var correct = Math.floor(Math.random()*70)+10;
var corner = 90 - correct;
var point = [1+8*Math.cos(correct * Math.PI / 180), 1+8*Math.sin(correct * Math.PI / 180)];
result.jessie += 'D('+point [0] + ',' + point[1] + ') invisible; [BD]; alpha=<(C,B,D);' + corner +'\u00b0=<(D,B,A);';
var answers = [];
var stopnow = false;
for (var i = 0; (answers.length < 3 && !stopnow && i < 100); i++){
// Be careful with while loop!!! Using for loop upto 100 to make sure to exit.
var newans = Math.floor(Math.random()*40)-20+correct;
if (newans > 0 && newans < 90 && newans !== correct && answers.indexOf(newans) === -1){
answers.push(newans);
}
}
answers.push(correct);
answers.sort(function(a,b){return Math.random()-0.5;});
result.correct = answers.indexOf(correct);
for (var i = 0; i < 4; i++){
answers[i] = answers[i] + '\u00b0';
}
result.qanswers = answers;
return result;
/*}}}*/
!complement_shortanswer
/*{{{*/
/** sum of angles in triangle: shortanswer **/
this.dict = {
'qtext': {
'en': '<p>A right angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>',
'fi': '<p>Suora kulma on jaettu kahteen pienempään kulmaan. Mikä on kulman \\(\\alpha\\) arvo asteina?</p>',
'sv': '<p>En rät vinkel är indelad i två mindre vinklar. Hur stor är vinkeln \\(\\alpha\\) (i grader)?</p>',
'et': '<p>A right angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'shortanswer',
qtext: this.localize('qtext'),
lblabels: [],
haspicture: true,
jessie: 'A(1,9) invisible; B(1,1) invisible; C(9,1) invisible; [AB]; [BC]; '
}
var correct = Math.floor(Math.random()*70)+10;
var corner = 90 - correct;
var point = [1+8*Math.cos(correct * Math.PI / 180), 1+8*Math.sin(correct * Math.PI / 180)];
result.jessie += 'D('+point [0] + ',' + point[1] + ') invisible; [BD]; alpha=<(C,B,D);' + corner +'\u00b0=<(D,B,A);';
result.correct = [''+correct];
result.check = function(answer, corrects){
return (answer === corrects[0] || answer === (corrects + '^{\\circ}'));
}
return result;
/*}}}*/
!supplement_multichoice
/*{{{*/
/** sum of supplementary angles: multichoice **/
this.dict = {
'qtext': {
'en': '<p>Straight angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>',
'fi': '<p>Oikokulma on jaettu kahteen pienempään kulmaan. Mikä on kulman \\(\\alpha\\) arvo asteina?</p>',
'sv': '<p>En rak vinkel är indelad i två mindre vinklar. Hur stor är vinkeln \\(\\alpha\\) (i grader)?</p>',
'et': '<p>Straight angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'multichoice',
qtext: this.localize('qtext'),
lblabels: [],
haspicture: true,
jessie: 'A(1,3) invisible; B(5,3) invisible; C(9,3) invisible; [AB]; [BC]; '
}
var correct = Math.floor(Math.random()*160)+10;
var corner = 180 - correct;
var point = [5+4*Math.cos(correct * Math.PI / 180), 3+4*Math.sin(correct * Math.PI / 180)];
result.jessie += 'D('+point [0] + ',' + point[1] + ') invisible; [BD]; alpha=<(C,B,D);' + corner +'\u00b0=<(D,B,A);';
var answers = [];
var stopnow = false;
for (var i = 0; (answers.length < 3 && !stopnow && i < 100); i++){
// Be careful with while loop!!! Using for loop upto 100 to make sure to exit.
var newans = Math.floor(Math.random()*40)-20+correct;
if (newans > 0 && newans < 180 && newans !== correct && answers.indexOf(newans) === -1){
answers.push(newans);
}
}
answers.push(correct);
answers.sort(function(a,b){return Math.random()-0.5;});
result.correct = answers.indexOf(correct);
for (var i = 0; i < 4; i++){
answers[i] = answers[i] + '\u00b0';
}
result.qanswers = answers;
return result;
/*}}}*/
!supplement_shortanswer
/*{{{*/
/** sum of angles in triangle: shortanswer **/
this.dict = {
'qtext': {
'en': '<p>Straight angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>',
'fi': '<p>Oikokulma on jaettu kahteen pienempään kulmaan. Mikä on kulman \\(\\alpha\\) arvo asteina?</p>',
'sv': '<p>En rak vinkel är indelad i två mindre vinklar. Hur stor är vinkeln \\(\\alpha\\) (i grader)?</p>',
'et': '<p>Straight angle was divided in two smaller angles. How big is the angle \\(\\alpha\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'shortanswer',
qtext: this.localize('qtext'),
lblabels: [],
haspicture: true,
jessie: 'A(1,3) invisible; B(5,3) invisible; C(9,3) invisible; [AB]; [BC]; '
}
var correct = Math.floor(Math.random()*160)+10;
var corner = 180 - correct;
var point = [5+4*Math.cos(correct * Math.PI / 180), 3+4*Math.sin(correct * Math.PI / 180)];
result.jessie += 'D('+point [0] + ',' + point[1] + ') invisible; [BD]; alpha=<(C,B,D);' + corner +'\u00b0=<(D,B,A);';
result.correct = [''+correct];
result.check = function(answer, corrects){
return (answer === corrects[0] || answer === (corrects + '^{\\circ}'));
}
return result;
/*}}}*/
!ratio_image
//{{{
/** Divide the segment with given ratio: image **/
this.dict = {
qtext: {
'en': '<p>Move the point \\(P\\) so, that it divides the segment \\(AB\\) in ratio {{{ratio}}}.</p>',
'fi': '<p>Siirrä pistettä \\(P\\) niin, että se jakaa janan \\(AB\\) suhteessa {{{ratio}}}.</p>',
'sv': '<p>Flytta punkten \\(P\\), så att den delar sträckan \\(AB\\) i förhållandet {{{ratio}}}.</p>',
'et': '<p>Move the point \\(P\\) so, that it divides the segment \\(AB\\) in ratio {{{ratio}}}.</p>'
},
'correct': {
'en': 'Correct!',
'fi': 'Oikein!',
'sv': 'Rätt svar!',
'et': 'Correct!'
},
'wrong': {
'en': 'Wrong!',
'fi': 'Väärin!',
'sv': 'Fel!',
'et': 'Wrong!'
},
'decimal': {
'en': '.',
'fi': ',',
'sv': ',',
'et': ','
},
'length of AB': {
'en': 'The length of segment \\(AB\\): ',
'fi': 'Janan \\(AB\\) pituus: ',
'sv': 'Längd av \\(AB\\): ',
'et': 'The length of segment \\(AB\\): '
},
'length of AP': {
'en': 'The length of segment \\(AP\\): ',
'fi': 'Janan \\(AP\\) pituus: ',
'sv': 'Längd av \\(AP\\): ',
'et': 'The length of segment \\(AP\\): '
},
'length of PB': {
'en': 'The length of segment \\(PB\\): ',
'fi': 'Janan \\(PB\\) pituus: ',
'sv': 'Längd av \\(PB\\): ',
'et': 'The length of segment \\(PB\\): '
}
};
var scales = [0.5, 1, 2, 3, 4, 5];
var scale = scales[Math.floor(Math.random()* scales.length)];
var ap = 1+Math.floor(Math.random() * 8);
var pb = 1+Math.floor(Math.random() * 8);
var ab = ap+pb;
var yscale = ((ab+2)*scale)*75/600;
var result = {
qtype: 'image',
qstyle: 'widepic',
qtext: this.localize('qtext'),
ltlabels: ['A'],
rtlabels: ['B'],
haspicture: true,
feedback: '<p class="corrfeedback">'+this.localize('correct')+'</p><p class="wrongfeedback">'+this.localize('wrong')+'</p><p>'+this.localize('length of AB')+(ab * scale).toString().replace('.',this.localize('decimal'))+'<br />'+this.localize('length of AP')+'\\(\\frac{'+ap+'}{'+(ab)+'}\\cdot '+(ab*scale).toString().replace('.',this.localize('decimal'))+'='+(ab*scale*ap/ab).toString().replace('.',this.localize('decimal'))+'\\)<br />'+this.localize('length of PB')+'\\(\\frac{'+pb+'}{'+(ab)+'}\\cdot '+(ab*scale).toString().replace('.',this.localize('decimal'))+'='+(ab*scale*pb/ab).toString().replace('.',this.localize('decimal'))+'\\)</p>',
jessiebb: [-1*scale, yscale,scale*ab +scale, -1*yscale],
jessie: 'A(0,0); B('+(scale*ab)+',0); g=[AB] nolabel; P(g,'+(scale*ab*0.5)+',0);',
jessiecorrect: 'C('+(scale*ap)+', 0) invisible; k=[CB] nolabel; Q('+(scale*ap)+','+ (-0.2*scale) +') nolabel;',
jessiestyles: {
question: {
'lines': {
'strokeColor': 'blue'
}
},
questionafter: {
'P': {
'fixed': true
}
},
correct: {
'lines': {
'strokeColor': 'violet',
'shadow': false
},
'C': {
'color': 'black'
},
'Q': {
'face': '^',
'size': 6,
'color': 'green'
}
}
}
}
result.qtext = result.qtext.replace('{{{ratio}}}', ap + ':' + pb);
result.correct = [ap, pb];
result.getAnswer = function(board){
var pointA = board.elementsByName['A'];
var pointB = board.elementsByName['B'];
var pointP = board.elementsByName['P'];
var ap = pointA.Dist(pointP);
var pb = pointP.Dist(pointB);
return [ap, pb];
}
result.check = function(answer, correct){
var ratio = ((answer[0] * correct[1]) / (answer[1] * correct[0]));
var result = (0.9 < ratio && ratio < 1.1);
return result;
}
return result;
//}}}
!triangletype_image
//{{{
/** Make a triangle of given type: image **/
this.dict = {
'triangletypes': {
'en': ['right', 'acute', 'obtuse', 'equilateral', 'isosceles', 'acute', 'obtuse'],
'fi': ['suorakulmainen','teräväkulmainen','tylppäkulmainen','tasasivuinen','tasakylkinen','teräväkulmainen', 'tylppäkulmainen'],
'sv': ['rätvinklig', 'spetsig', 'trubbig', 'liksidig', 'likbent', 'spetsig', 'trubbig'],
'et': ['täisnurkne', 'teravnurkne', 'nürinurkne', 'võrdkülgne', 'võrdhaarne', 'teravnurkne', 'nürinurkne']
},
'qtext': {
'en': '<p>Move the corner points of the triangle so that you get <strong>%1 triangle</strong>.</p>',
'fi': '<p>Siirrä kolmion kulmapisteitä niin, että muodostuu <strong>%1 kolmio</strong>.</p>',
'sv': '<p>Flytta på punkterna så att triangeln blir <strong>%1</strong>.</p>',
'et': '<p>Move the corner points of the triangle so that you get <strong>%1 triangle</strong>.</p>'
},
'correct': {
'en': 'Correct!',
'fi': 'Oikein!',
'sv': 'Rätt svar!',
'et': 'Correct!'
},
'wrong': {
'en': 'Wrong!<br />See the model image.',
'fi': 'Väärin!<br />Katso mallikuviota.',
'sv': 'Fel!<br />Titta på exempelbilden bredvid.',
'et': 'Wrong!<br />See the model image.'
}
}
var triangletypes = this.localize('triangletypes');
var examples = [
[[1,1],[2,1],[1,3]],
[[1,1], [2.5,1], [1.5,2.5]],
[[1.5,1], [2.5,1], [1,2.5]],
[[1,1], [2.5,1], [1.75, 1+Math.sqrt(3)* 0.75]],
[[1,1], [2.5,1], [1.75, 2.7]],
[[1,1], [2.5,1], [1.5,2.5]],
[[1.5,1], [2.5,1], [1,2.5]]
];
var apoints = [[8,2],[8,3],[8,5],[8,8]];
var bpoints = [[2,2],[3,2],[5,2],[7,2]];
var cpoints = [[2,3],[2,5],[3,6],[6,8]];
var apoint = apoints[Math.floor(Math.random()*apoints.length)];
var bpoint = bpoints[Math.floor(Math.random()*bpoints.length)];
var cpoint = cpoints[Math.floor(Math.random()*cpoints.length)];
var triangletypeindex = Math.floor(Math.random()*triangletypes.length);
var triangletype = triangletypes[triangletypeindex];
var exampletriangle = examples[triangletypeindex][Math.floor(Math.random()*examples[triangletypeindex].length)];
var result = {
qtype: 'image',
qstyle: 'default',
qtext: this.localize('qtext').replace(/%1/g, triangletype),
haspicture: true,
feedback: '<p class="corrfeedback">'+this.localize('correct')+'</p><p class="wrongfeedback">'+this.localize('wrong')+'</p>',
jessiebb: [0, 10, 10, 0],
jessie: 'A('+apoint[0]+','+apoint[1]+') nolabel; B('+bpoint[0]+','+bpoint[1]+') nolabel; C('+cpoint[0]+','+cpoint[1]+') nolabel; [AB] nolabel; [BC] nolabel; [CA] nolabel; Pol[A,B,C] nolabel; alpha=<(C,A,B); beta=<(A,B,C); gamma=<(B,C,A); alpha1=<(B,A,C); beta1=<(C,B,A); gamma1=<(A,C,B);',
//jessie: 'O(5,5) invisible; k1=k(O,3) invisible; A(k1,8,5) nolabel; B(k1,5,2) nolabel; C(k1) nolabel; [AB] nolabel; [BC] nolabel; [CA] nolabel; Pol[A,B,C] nolabel; alpha=<(C,A,B); beta=<(A,B,C); gamma=<(B,C,A);',
jessiecorrect: ['D('+examples[triangletypeindex][0][0]+', '+examples[triangletypeindex][0][1]+') invisible;',
'E('+examples[triangletypeindex][1][0]+', '+examples[triangletypeindex][1][1]+') invisible;',
'F('+examples[triangletypeindex][2][0]+', '+examples[triangletypeindex][2][1]+') invisible;',
'[DE] nolabel; [EF] nolabel; [FD] nolabel;'].join(' '),
jessiehidecorrect: true,
jessiestyles: {
question: {
'lines': {
'strokeColor': 'blue'
},
'points': {
'fixed': false,
'face': 'o',
'size': 4
},
'angles': {
'radius': 0.8
}
},
questionafter: {
'P': {
'fixed': true
}
},
correct: {
'lines': {
'strokeColor': 'green',
'shadow': false
},
'points': {
'fixed': true,
'color': 'green'
},
'angles': {
'radius': 0.4
}
}
},
jessielabels: {
question: {
'alpha': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['alpha'];
return function(){
var alphasize = Math.round(board.angle(C,A,B) * 180 / Math.PI);
var betasize = Math.round(board.angle(A,B,C) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (Math.round(board.angle(C,A,B) * 180 / Math.PI) <= 0 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return (Math.abs(Math.round(board.angle(C,A,B) * 180 / Math.PI))) + '°';
};
},
'alpha1': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['alpha1'];
return function(){
var alphasize = Math.round(board.angle(B,A,C) * 180 / Math.PI);
var betasize = Math.round(board.angle(C,B,A) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (Math.round(board.angle(B,A,C) * 180 / Math.PI) <= 0 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return (Math.abs(Math.round(board.angle(C,A,B) * 180 / Math.PI))) + '°';
};
},
'beta': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['beta'];
return function(){
var alphasize = Math.round(board.angle(C,A,B) * 180 / Math.PI);
var betasize = Math.round(board.angle(A,B,C) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (Math.round(board.angle(A,B,C) * 180 / Math.PI) <= 0 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return (Math.abs(Math.round(board.angle(A,B,C) * 180 / Math.PI))) + '°';
};
},
'beta1': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['beta1'];
return function(){
var alphasize = Math.round(board.angle(B,A,C) * 180 / Math.PI);
var betasize = Math.round(board.angle(C,B,A) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (Math.round(board.angle(C,B,A) * 180 / Math.PI) <= 0 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return (Math.abs(Math.round(board.angle(A,B,C) * 180 / Math.PI))) + '°';
};
},
'gamma': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['gamma'];
return function(){
var alphasize = Math.round(board.angle(C,A,B) * 180 / Math.PI);
var betasize = Math.round(board.angle(A,B,C) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (gammasize <= 0 || gammasize > 180 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return Math.abs(gammasize) + '°';
};
},
'gamma1': function(construction){
var A = construction['A'];
var B = construction['B'];
var C = construction['C'];
var board = A.board;
var angle = construction['gamma1'];
return function(){
var alphasize = Math.round(board.angle(B,A,C) * 180 / Math.PI);
var betasize = Math.round(board.angle(C,B,A) * 180 / Math.PI);
var gammasize = 180 - alphasize - betasize;
if (gammasize <= 0 || gammasize > 180 || alphasize === 0 || betasize === 0 || gammasize === 0){
angle.setProperty({visible: false});
} else {
angle.setProperty({visible: true});
}
return Math.abs(gammasize) + '°';
};
}
}
},
correct: [triangletypeindex],
getAnswer: function(board){
return [board.elementsByName['α'], board.elementsByName['β'], board.elementsByName['γ']];
},
check: function(answer, correct){
var angles = answer;
var points = [
[angles[0].point2, angles[0].point1, angles[0].point3],
[angles[1].point2, angles[1].point1, angles[1].point3],
[angles[2].point2, angles[2].point1, angles[2].point3]
];
var sizes = [
Math.round(JXG.Math.Geometry.trueAngle(points[0][0], points[0][1], points[0][2])),
Math.round(JXG.Math.Geometry.trueAngle(points[1][0], points[1][1], points[1][2]))
];
sizes.push(180-sizes[0]-sizes[1]);
var iscorrect = false;
switch (correct[0]) {
case 0:
iscorrect = (sizes[0] === 90 || sizes[1] === 90 || sizes[2] === 90 || sizes[0] === 270 || sizes[1] === 270 || sizes[2] === 270);
break;
case 1:
case 5:
iscorrect = (sizes[0] < 90 && sizes[1] < 90 && sizes[2] < 90);
break;
case 2:
case 6:
iscorrect = (sizes[0] > 90 || sizes[1] > 90 || sizes[2] > 90);
break;
case 3:
iscorrect = (sizes[0] === 60 && sizes[1] === 60 && sizes[2] === 60);
break;
case 4:
iscorrect = (sizes[0] === sizes[1] || sizes[1] === sizes[2] || sizes[2] === sizes[0]);
break;
default:
iscorrect = false;
break;
}
return iscorrect;
}
}
if (result.correct > 4){
result.jessielabels = {};
result.jessiestyles.question.angles.visible = false;
}
return result;
//}}}
!multichoice
/*{{{*/
/** sum of angles in triangle: multichoice **/
this.dict = {
qtext: {
'en': '<p>What is the size of angle \\(\\beta\\) (in degrees)?</p>',
'fi': '<p>Mikä on kulman \\(\\beta\\) arvo asteina?</p>',
'sv': '<p>Hur stor är vinkeln \\(\\beta\\) (i grader)?</p>',
'et': '<p>What is the size of angle \\(\\beta\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'multichoice',
qtext: this.localize('qtext'),
lblabels: ['A'],
haspicture: true
}
var correct = Math.floor(Math.random()*95)+25;
var corners = [Math.floor((180-correct) * (Math.random()*0.5+0.25))];
corners.push(180-correct-corners[0]);
var coordinates = {'A': [0,0], 'C': [8/(Math.tan(corners[0]*Math.PI/180)),8]};
coordinates['B'] = [coordinates['C'][0] + 8/(Math.tan(correct * Math.PI/180)), 0];
var maxcoord = Math.max(coordinates['A'][0], coordinates['B'][0], coordinates['C'][0]);
var mincoord = Math.min(coordinates['A'][0], coordinates['B'][0], coordinates['C'][0]);
var maxcoordy = Math.max(coordinates['A'][1], coordinates['B'][1], coordinates['C'][1]);
var mincoordy = Math.min(coordinates['A'][1], coordinates['B'][1], coordinates['C'][1]);
var scale = Math.min(8/(maxcoord - mincoord), 8/(maxcoordy - mincoordy));
var xoffset = (10 - (scale * (maxcoord-mincoord)))/2;
var yoffset = (10 - (scale * coordinates['C'][1]))/2;
coordinates = {
'A': [xoffset-scale*mincoord+ scale*coordinates['A'][0], yoffset],
'B': [xoffset-scale*mincoord+ scale*coordinates['B'][0], yoffset],
'C': [xoffset-scale*mincoord+ scale*coordinates['C'][0], yoffset+scale*coordinates['C'][1]]
};
result.jessie = [
'A('+coordinates['A'][0]+','+coordinates['A'][1]+');',
'B('+coordinates['B'][0]+','+coordinates['B'][1]+');',
'C('+coordinates['C'][0]+','+coordinates['C'][1]+');',
'[AB] nolabel; [BC] nolabel; [CA] nolabel;',
'beta=<(C,B,A);',
corners[0]+'\u00b0=<(B,A,C);',
corners[1]+'\u00b0=<(A,C,B);',
].join(' ');
var answers = [];
var stopnow = false;
while (answers.length < 3 && !stopnow){
var newans = Math.floor(Math.random()*40)-20+correct;
if (newans > 0 && newans !== correct && answers.indexOf(newans) === -1){
answers.push(newans);
}
}
answers.push(correct);
answers.sort(function(a,b){return Math.random()-0.5;});
result.correct = answers.indexOf(correct);
for (var i = 0; i < 4; i++){
answers[i] = answers[i] + '\u00b0';
}
result.qanswers = answers;
return result;
/*}}}*/
!shortanswer
/*{{{*/
/** sum of angles in triangle: shortanswer **/
this.dict = {
qtext: {
'en': '<p>What is the size of angle \\(\\beta\\) (in degrees)?</p>',
'fi': '<p>Mikä on kulman \\(\\beta\\) arvo asteina?</p>',
'sv': '<p>Hur stor är vinkeln \\(\\beta\\) (i grader)?</p>',
'et': '<p>What is the size of angle \\(\\beta\\) (in degrees)?</p>'
}
}
var result = {
qtype: 'shortanswer',
qtext: this.localize('qtext'),
lblabels: ['A'],
haspicture: true
}
var correct = Math.floor(Math.random()*95)+25;
var corners = [Math.floor((180-correct) * (Math.random()*0.5+0.25))];
corners.push(180-correct-corners[0]);
var coordinates = {'A': [0,0], 'C': [8/(Math.tan(corners[0]*Math.PI/180)),8]};
coordinates['B'] = [coordinates['C'][0] + 8/(Math.tan(correct * Math.PI/180)), 0];
var maxcoord = Math.max(coordinates['A'][0], coordinates['B'][0], coordinates['C'][0]);
var mincoord = Math.min(coordinates['A'][0], coordinates['B'][0], coordinates['C'][0]);
var maxcoordy = Math.max(coordinates['A'][1], coordinates['B'][1], coordinates['C'][1]);
var mincoordy = Math.min(coordinates['A'][1], coordinates['B'][1], coordinates['C'][1]);
var scale = Math.min(8/(maxcoord - mincoord), 8/(maxcoordy - mincoordy));
var xoffset = (10 - (scale * (maxcoord-mincoord)))/2;
var yoffset = (10 - (scale * coordinates['C'][1]))/2;
coordinates = {
'A': [xoffset-scale*mincoord+ scale*coordinates['A'][0], yoffset],
'B': [xoffset-scale*mincoord+ scale*coordinates['B'][0], yoffset],
'C': [xoffset-scale*mincoord+ scale*coordinates['C'][0], yoffset+scale*coordinates['C'][1]]
};
result.jessie = [
'A('+coordinates['A'][0]+','+coordinates['A'][1]+');',
'B('+coordinates['B'][0]+','+coordinates['B'][1]+');',
'C('+coordinates['C'][0]+','+coordinates['C'][1]+');',
'[AB] nolabel; [BC] nolabel; [CA] nolabel;',
'beta=<(C,B,A);',
corners[0]+'\u00b0=<(B,A,C);',
corners[1]+'\u00b0=<(A,C,B);',
].join(' ');
result.correct = [''+correct];
result.check = function(answer, corrects){
return (answer === corrects[0] || answer === (corrects + '^{\\circ}'));
}
return result;
/*}}}*/
!usage
{{{[img[envelope.png]]}}}
[img[envelope.png]]
!notes
Envelope
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[[eulexia.ttf|eulexia.ttf]]}}}
[[eulexia.ttf|eulexia.ttf]]
!notes
SIL-OFL licensed typeface to assist in helping with some symptoms of dyslexia.
http://antijingoist.github.com/Eulexia/
!License
[[OFL.txt]]
[[OFL (SIL Open Font License)|http://scripts.sil.org/OFL]]
!type
application/octet-stream
!url
!data
data:application/octet-stream;base64,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AB4AG//4AB8AHP/3ACAAHf/3ACEAHv/3ACIAH//3ACMAIP/2ACQAIf/2ACUAIv/2ACYAI//2ACcAI//1ACgAJP/1ACkAJf/1ACoAJv/1ACsAJ//0ACwAKP/0AC0AKf/0AC4AKv/0AC8AK//zADAALP/zADEALP/zADIALf/yADMALv/yADQAL//yADUAMP/yADYAMf/xADcAMv/xADgAM//xADkANP/xADoANP/wADsANf/wADwANv/wAD0AN//wAD4AOP/vAD8AOf/vAEAAOv/vAEEAO//vAEIAPP/uAEMAPf/uAEQAPf/uAEUAPv/uAEYAP//tAEcAQP/tAEgAQf/tAEkAQv/tAEoAQ//sAEsARP/sAEwARf/sAE0ARf/rAE4ARv/rAE8AR//rAFAASP/rAFEASf/qAFIASv/qAFMAS//qAFQATP/qAFUATf/pAFYATv/pAFcATv/pAFgAT//pAFkAUP/oAFoAUf/oAFsAUv/oAFwAU//oAF0AVP/nAF4AVf/nAF8AVv/nAGAAV//nAGEAV//mAGIAWP/mAGMAWf/mAGQAWv/lAGUAW//lAGYAXP/lAGcAXf/lAGgAXv/kAGkAX//kAGoAX//kAGsAYP/kAGwAYf/jAG0AYv/jAG4AY//jAG8AZP/jAHAAZf/iAHEAZv/iAHIAZ//iAHMAaP/iAHQAaP/hAHUAaf/hAHYAav/hAHcAa//hAHgAbP/gAHkAbf/gAHoAbv/gAHsAb//fAHwAcP/fAH0AcP/fAH4Acf/fAH8Acv/eAIAAc//eAIEAdP/eAIIAdf/eAIMAdv/dAIQAd//dAIUAeP/dAIYAef/dAIcAef/cAIgAev/cAIkAe//cAIoAfP/cAIsAff/bAIwAfv/bAI0Af//bAI4AgP/bAI8Agf/aAJAAgv/aAJEAgv/aAJIAg//aAJMAhP/ZAJQAhf/ZAJUAhv/ZAJYAh//YAJcAiP/YAJgAif/YAJkAiv/YAJoAiv/XAJsAi//XAJwAjP/XAJ0Ajf/XAJ4Ajv/WAJ8Aj//WAKAAkP/WAKEAkf/WAKIAkv/VAKMAk//VAKQAk//VAKUAlP/VAKYAlf/UAKcAlv/UAKgAl//UAKkAmP/UAKoAmf/TAKsAmv/TAKwAm//TAK0AnP/SAK4AnP/SAK8Anf/SALAAnv/SALEAn//RALIAoP/RALMAof/RALQAov/RALUAo//QALYApP/QALcApP/QALgApf/QALkApv/PALoAp//PALsAqP/PALwAqf/PAL0Aqv/OAL4Aq//OAL8ArP/OAMAArf/OAMEArf/NAMIArv/NAMMAr//NAMQAsP/MAMUAsf/MAMYAsv/MAMcAs//MAMgAtP/LAMkAtf/LAMoAtf/LAMsAtv/LAMwAt//KAM0AuP/KAM4Auf/KAM8Auv/KANAAu//JANEAvP/JANIAvf/JANMAvv/JANQAvv/IANUAv//IANYAwP/IANcAwf/IANgAwv/HANkAw//HANoAxP/HANsAxf/HANwAxv/GAN0Ax//GAN4Ax//GAN8AyP/FAOAAyf/FAOEAyv/FAOIAy//FAOMAzP/EAOQAzf/EAOUAzv/EAOYAz//EAOcAz//DAOgA0P/DAOkA0f/DAOoA0v/DAOsA0//CAOwA1P/CAO0A1f/CAO4A1v/CAO8A1//BAPAA2P/BAPEA2P/BAPIA2f/BAPMA2v/AAPQA2//AAPUA3P/AAPYA3f+/APcA3v+/APgA3/+/APkA4P+/APoA4P++APsA4f++APwA4v++AP0A4/++AP4A5P+9AP8A5f+9AAAAFwAAANwJCwkAAwMCBAYGCQcDAwQEBQIEAwMGBQYGBQUFBQUGAwIFBgUFCQcGBgcFBQcHAgQGBQgHCAUIBwYGBwcJBwYGAwMDBQcCBgUFBQUEBgUCAwUCCAUGBQUDBQMFBQgGBQUEAgMGAgUGBgYCBgQHBQUFBwcFBQQEAgYFAgIDBQUICAgFBgYGBgYHCQYFBQUFAgICAgYGBwcHBwcFBwYGBgYGBwYGBgYGBgYJBQUFBQUDAwQDBgUFBQUFBQUFBQUFBQUGBQIJCQQEBAcLAgICBAQEBAMDBQMGCAUEBQAACgwKAAMDAgUGBwoHAwQEBQUDBAMDBwUGBgYGBgUGBgQDBgcGBQoHBgcIBgYHBwMEBwUJCAgGCAgHBggHCggHBwMDAwUHAwYGBQYGBAYGAgMFAwkGBgYGBAUDBgYIBgYFBAIEBgMFBgYGAgYFCAUGBggHBQUFBQIGBgMDBAUGCQkJBQcHBwcHCAsHBgYGBgMDAwMHBwgICAgIBggHBwcHBwcGBgYGBgYGCQUGBgYGAwMEBAYGBgYGBgYFBgUFBQUGBgYDCgoEBAUHDAICAgQEBAQDAwUEBggGBQYAAAsNCwADBAMFBwcLCAMEBQUGAwUDBAcGBwcGBgYGBwcEAwcHBwYLCAcICAcGCAgDBQgGCggJBwkICAcICAwJCAgEBAQGCAMGBgYGBgQHBgMDBgMKBwcGBgQGBAcGCQcGBgQDBAcDBgcHBwMHBQkFBwYJCAUGBQUDBwYDAwQGBgkKCQYHBwcHBwgMCAYGBgYDAwMDCAcJCQkJCQYJBwcHBwgIBwcHBwcHBwoGBgYGBgMDBQQHBgYGBgYGBgcGBgYGBwcHAwsLBQUFCA0DAgIFBQUEBAQGBAcJBwUGAAAMDgwAAwQDBQgIDAkDBQUFBgMFBAQHBgcHBwcHBgcHBQMHCAcHDAkHCAkHBwkJAwUIBgsJCgcKCAgHCQkNCQgIBAQEBwkDCAcHBwcEBwcDBAYDCwcHBwcEBgQHBwoIBwcFAwUIAwYHBwgDBwUKBgcHCgkFBgUFAwcHAwMEBgcKCwoHCAgICAgJDQkHBwcHAwMDAwgICQkJCQkHCQgICAgJCAgHBwcHBwcLBgcHBwcEBAUEBwcHBwcHBwYHBgYGBgcHBwMMDAUFBgkOAwMDBQUFBQQEBgUICgcFBwAADQ8NAAQFAwYICAwKBAUFBgcDBgQECAcIBwcICAcIBwUDCAkIBw0JCQkKCAcKCgQGCQcMCgoICgkJCAkJDgoJCQUEBAcKBAgHBwcHBQcHAwQHAwwICAcHBQcECAcLCAgHBQMFCAQHCAgIAwgGCwYICAsKBgcGBQMHBwMDBQYICwsLBwkJCQkJCg4JBwcHBwQEBAQJCQoKCgoKCAoJCQkJCQkICAgICAgIDAcHBwcHBAQFBQgHBwcHBwcHCAcHBwcICAgDDg0FBQYJDwMDAwUFBQUEBAcFCAsIBggAAA8SDwAEBQQHCgoOCwQGBgcIBAcFBQkICAgICQkICQgGBAkKCQgOCwoKCwkICwsEBwsIDgsMCQsLCgkKCxAMCgoFBQUICwQJCAgJCQYICQQFCAQNCQkJCAYIBQkJDQoJCAYEBgkECAkJCQQIBgwICQkMCwYIBgYECAkEBAUHCQ0NDQgKCgoKCgsQCwgICAgEBAQECgoMDAwMDAkMCgoKCgsKCQkJCQkJCQ4ICQkJCQUFBgYICAkJCQkJCAkICAgICQkJBBAPBgYHCxIDAwMGBgYGBQUIBgkNCQcJAAAQExAABAYEBwoKDwwFBgYHCQQHBQUJCAkJCQkJCAkJBgQKCgoJDwwKCwsKCQwMBAcLCQ8MDAoMCwsKCwwRDQsLBgUFCQwECgkJCQkGCQkEBQgEDgoJCQkGCQUKCQ0KCQkGBAYKBAgKCQoECQYNCAkJDQwHCAcGBAkJBAQGBwkODg4JCwsLCwsMEQsJCQkJBAQEBAsLDAwMDAwJDAsLCwsMCgoKCgoKCgoPCAkJCQkFBQcGCQkJCQkJCQgKCAgICAoJCgQREAcGCAwTBAQEBgYGBgUFCAYKDQkHCQAAERQRAAUGBAgLCxAMBQcGCAkEBwUGCgkJCQoKCgkKCQcFCgsKCRAMCwwMCgkNDAUIDAkQDA0KDQwMCwsMEg0MDAYFBgkNBQoKCQoKBgkKBAUJBA8KCgoKBgkGCgoOCwoJBwQGCwUJCgkLBAkHDggKCg4NBwkHBwQJCgQFBggKDw8OCQwMDAwMDRIMCQkJCQUFBQUMCw0NDQ0NCg0LCwsLDAsLCgoKCgoKEAkKCgoKBQUHBgkKCgoKCgoJCgkJCQkKCQoEEhEHBggMFAQEBAYGBgcGBgkGCw4KCAoAABMWEwAFBwUJDAsSDgUHBwkKBQgGBgsKCwsLCwsKCwoHBQsMCwoSDgwNDQwLDg4FCQ0KEQ4ODA4NDQwMDhQPDQ0HBgYKDgULCwoLCwcLCwUGCgURCwoLCwcKBgsLEAwLCgcFBwwFCgwLDAUKCBAJCwsQDgcKCAcFCwsFBQcICxAREAoNDQ0NDQ4UDgsLCwsFBQUFDQ0PDw8PDwsPDQ0NDQ4MDAwMDAwMDBIKCwsLCwYGCAcKCwsLCwsLCgsKCgoKCwoLBRQTCAcJDhYEBAQIBwcHBgYKBwwQCwkLAAAVGRUABgcFCQ4NFA8GCAgKCwUJBgcNCw0NDAwMCwwMCAYNDg0LFA8ODg8NDBAPBgkPCxMQEQ0QEA4NEA8WEA4OBwcHDBAGDQwLDAwHDQwFBwsFEw0MDAwICwcNDBINDAsIBQgNBgsNDQ0FDAoRCgwMEQ8JCwkJBQ0MBQYICgwSEhILDg4ODg4QFg8MDAwMBgYGBg4OEBAQEBAMEA4ODg4PDg0NDQ0NDQ0UCwwMDAwGBgkIDAwMDAwMDAsNCwsLCwwMDAUWFQkICg8ZBQUFCQkJCAcHCwgNEgwKDAAAGBwYAAcIBgsQDxcSBwkJCw0GCgcIDw0ODg4ODgwODgkGDhAODRcSEBARDw0SEgcLEQ0WEhMPExEQDxERGRMREAgICA0SBg8ODQ4OCA4OBgcNBhUPDw4OCQ0IDg4UDw4NCQYJDwcMDw4PBg4LFAsODhQSCg0LCgYODgYGCQwOFRUUDRAQEBAQEhkRDQ0NDQYGBgYREBMTExMTDhMQEBAQERAPDw8PDw8PFw0ODg4OBwcKCQ0NDg4ODg4MDg0NDQ0ODg4GGRgKCQwRHAUFBQoKCgkICAwJDxQOCw4AABsgGwAICQcMERAaFAgKCQwOBwwICRAOEA8PEBAOEA8KBxASEA8aFBETFBAPFBQHDBMOGRQWEBUTExETFBwVExIJCQkPFAcQDw8PEAoPDwcIDgcYEBAPDwoPCRAPFxEQDwoGChEHDhEQEQcPCxYNEBAWFAwODAsHDxAHBwoNEBcYFw8SEhISEhUcEw8PDw8HBwcHExIVFRUVFRAVEhISEhMRERERERERERoODw8PDwgICwoQDw8PDw8PDhAODg4OEA8QBxwbCwsNFCAGBgYKCwsLCQkOChEXEAwQAAAdIh0ACAoHDRMSHBUICwsNEAcNCQoRDxAQEBERDxERCwgRExEQHBUTFBUSEBYVCA0UDxsVFxIWFBQSFBUeFxQUCgkKEBYIERAQEREKEREHCQ8IGhIREBALEAoRERgTERAKBwsSCA8SERIHEAwYDhERGBUMDwwMBxARCAgKDhEZGRkQFBQUFBQWHxUQEBAQCAgICBQUFxcXFxcRFxQUFBQVEhISEhISEhIcDxAQEBAJCQwLEBAREREREQ8RDw8PDxEQEQceHQwLDhUiBwcHCwsLCwoKDwsSGBENEQAAICUgAAkLCA4VFB8XCQwMDxEIDgoLExETExITExATEgwJExUTER8XFRYYExIYFwkOFxEdGRoTGRgWFBcXIRkWFgsKCxIYCRQSERISCxMSCAoRCB0TExISDBELExIbFBMRDQgMFAkQFBQUCBMPGhATExoYDREODQgTEggJCxATGxwbERYWFhYWGCIXEhISEgkJCQkWFhkZGRkZExkWFhYWFxUUFBQUFBQUHhESEhISCgoNDBMSEhISEhIQExERERETEhMIISANDBAXJQcHBw4NDQ0LCxAMFBsTDxMAACEnIQAJCwgPFRQgGAkNDA8SCA4KCxQRFBQTExMRFBMNCRQWFBIgGBYXGBQSGRgJDxcSHhkaFBoYFxUXGCMaFxcLCwsSGQkUExITEwsUEwgKEgkdFBQTEwwSCxQTHBUTEg0IDBUJERQUFQgTDxsQExMbGA0RDg4IFBMJCQwQExwdHBIWFhYWFhkjFxISEhIJCQkJFxYaGhoaGhMaFhYWFhgVFRQUFBQUFB8RExMTEwoKDgwTEhMTExMTERQRERERFBIUCCIhDgwQGCcIBwcODQ0NCwsRDBUcFA8TAAAlKyUACg0JERgXJBsLDg8RFAoQCwwWFBYWFRYVExYUDgoWGBYUJBsZGRsWFRwbChEaFCIcHRYdGxkXGhsnHRkZDQwNFBwKFxUUFRUNFRUJDBQKIRYVFRUOFAwWFR8YFhQOCQ4XChMXFhcJFRAeEhYWHhsQFA8QCRYVCgoNERYgIB8UGRkZGRkcJxoVFRUVCgoKChoZHR0dHR0WHRkZGRkbFxcXFxcXFxcjFBUVFRULCxAOFRUVFRUVFRMWExMTExYUFgkmJQ8OEhsrCAgIDw8PDwwMEw4XHxYRFQAAKjEqAAwPChMbGygfDBAQExcLEg0OGhYZGBgZGBYZGBALGRsZFykfHB0eGRcfHwsTHhYnHyIaIR4dGh4fLCEdHQ8NDhcfCxoYFxgYDhkYCg0WCyUZGhgYDxcOGRgjGxkXEAoQGgwWGhkaChkUIhUZGSIfEBYSEQoZGAsLDxUZJCUkFx0dHR0dICweFxcXFwsLCwsdHCEhISEhGSEcHBwcHhsaGhoaGhoaKBYYGBgYDQ0SEBgXGBgYGBgVGRYWFhYZFxkLLCoRDhQeMQoKChEREREODhYQGiMZExgAAC42LgANEAsVHh0sIg0SEhUZDBQOEBwYGxsaGxsYGxoSDBseGxksIh8gIhwaIiIMFSAZKiMlHCQhIB0gITAkIB8QDxAZIgwdGhkaGhAbGgsOGAwpHBsaGhEZDxwaJx0bGRELER0NGBwcHQsbFSYXGxsmIhIYFBMLGxoMDBEWGycoJxkfHx8fHyMwIRoaGhoMDAwMIB8kJCQkJBskHx8fHyEdHRwcHBwcHCwYGhoaGg4OExEbGhoaGhoaFxwYGBgYGxkbDDAuExAWITYKCgoTEhISDw8YER0mGxUbAAAyOjIADhEMFyAfMCUOExMXGw0WDxEfGh4eHB0dGh4dEw0eIR4bMCUhIiUeHCUlDhYjGy4mKB4nJSIfJSQ0JyIiERARGyUNHxwbHR0RHh0MEBsNLR4eHBwSGxEeHSogHRsTDBMfDhofHh8MHBcpFx4dKSUUGhQVDB0dDQ0SFx4rLCsbIiIiIiImNSQcHBwcDQ0NDSMiJycnJycdJyIiIiIkICAfHx8fHx8vGhwcHBwPDxUSHhwcHBwcHBkeGhoaGh4cHg00MhUSGCQ6CwsLFRUVFBEQGhMfKh4XHQAANj82AA8TDRgjIjQoDxUVGR0OGBESIBwgHx4gHxwgHhUPICMgHTQnJCUnIR4oKA8YJh0xKCshKyglIicnOColJRMREh4oDyIeHR8fEyAfDREdDjAhIB8eFB0SIB8tIiAdFA0UIg8cISAiDSAYLBkgICwoFR0XFw0gHw4PExkgLi8uHSUlJSUlKTkmHh4eHg8PDw8lJSoqKioqICokJCQkJyIiISEhISEhMx0fHx8fEBAXFB8eHx8fHx8bIBwcHBwgHiAOODYWExonPwwMDBYWFhUSEhwUIi0gGR8AADpEOgAQFA4aJSQ4KhAWFhofDxkSFCMfIiIhIiIeIiIWECMmIyA4KiYoKyMgKysQGikfNSwwIy4pKCQqKj0tKCgUExQgKxAkIR8hIRQjIQ4SHw80IyQhIRUfEyMhMSUiIBYOFiQQHiQjJA4iGjAcIiIwKxcfGBgOIiEPEBUcIjIzMSAnJycnJyw9KSAgICAQEBAQKCctLS0tLSItJycnJyolJSMjIyMjIzcfISEhIRISGBUiICEhISEhHSMeHh4eIiAiDzw6GBQcKkQNDQ0ZGBgXExMeFiQwIhoiAABDTkMAExcQHisqQDETGhoeJBEdFRcoIycnJicnIignGhIoLCglQTEsLjEpJTIxEh4vJD0zNSk1MC4qMDFGNC4uFxYXJTISKSYkJiYXKCYQFSQRPCkoJiYZJBYoJjgrJyQZEBkqEiIpKCoQJh43ICgnNzEbIxscESgnERIYHyg6OzkkLi4uLi4zRjAlJSUlEhISEi4tNDQ0NDQnNC0tLS0wKiopKSkpKSlAIyYmJiYUFBwZJyUmJiYmJiIoIyMjIygkKBFGQxwYITBODw8PGxsbGhYWIhkqOCgfJwAAS1hLABUaEiIwL0g3FR0dIigTIRcZLigsLCosLCcsKx0ULTEtKUg3MTM3LSo4NxQiNShFOD0uOzY0LzY3Tjs0MxoYGik4FC4qKSsrGi0rEhcoE0MtLSsqHCgZLSs/MCwpHRIcLxUmLiwvEisiPiQsLD43HSgfHxMsKxQUGyMsQEJAKTMzMzMzOU81KioqKhQUFBQ0Mzs7Ozs7LDszMzMzNi8vLi4uLi4uRygrKysrFxcgHCsqKysrKysmLScnJyctKS0TTksfGiQ2WBERER8fHx4ZGSYcLz8sIiwAAAAAAAMAAAADAAACmAABAAAAAAAcAAMAAQAAAeAABgHEAAAAIADdAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQAAAIQAhQCHAIkAkQCWAJwAoQCgAKIApACjAKUApwCpAKgAqgCrAK0ArACuAK8AsQCzALIAtAC2ALUAugC5ALsAvAAAAHAAYwBkAGgAzgB2AJ8AbgBqANYAdABpANcAhgCYAAAAcQAAAAAAZgB1AAAAAADUAAAAAABrAHoAAACmALgAfwBiAG0AAAAAANUAAABsAHsAAAAAAIAAgwCVAMEAwgDGAMcAywDMAMgAyQC3AAAAvwAAANEA0wDPANAAAAAAAAAAdwDKAM0AAACCAIoAgQCLAIgAjQCOAI8AjACTAJQAAACSAJoAmwCZAMAAwwDFAG8AAAAAAMQAeAAEALgAAAAqACAABAAKAH4ArAD/ATEBUwLGAtoC3CAUIBogHiAiIDogRCB0IKwhIiIPIkgiYP//AAAAIAChAK4BMQFSAsYC2gLcIBMgGCAcICIgOSBEIHQgrCEiIg8iSCJg////4//B/8D/j/9v/f396v3p4LPgsOCv4KzgluCN4F7gJ9+03sXejd53AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAC4AAAAKgAgAAQACgB+AKwA/wExAVMCxgLaAtwgFCAaIB4gIiA6IEQgdCCsISIiDyJIImD//wAAACAAoQCuATEBUgLGAtoC3CATIBggHCAiIDkgRCB0IKwhIiIPIkgiYP///+P/wf/A/4//b/39/er96eCz4LDgr+Cs4JbgjeBe4CfftN7F3o3edwABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuAAALEu4AAlQWLEBAY5ZuAH/hbgARB25AAkAA19eLbgAASwgIEVpRLABYC24AAIsuAABKiEtuAADLCBGsAMlRlJYI1kgiiCKSWSKIEYgaGFksAQlRiBoYWRSWCNlilkvILAAU1hpILAAVFghsEBZG2kgsABUWCGwQGVZWTotuAAELCBGsAQlRlJYI4pZIEYgamFksAQlRiBqYWRSWCOKWS/9LbgABSxLILADJlBYUViwgEQbsEBEWRshISBFsMBQWLDARBshWVktuAAGLCAgRWlEsAFgICBFfWkYRLABYC24AAcsuAAGKi24AAgsSyCwAyZTWLBAG7AAWYqKILADJlNYIyGwgIqKG4ojWSCwAyZTWCMhuADAioobiiNZILADJlNYIyG4AQCKihuKI1kgsAMmU1gjIbgBQIqKG4ojWSC4AAMmU1iwAyVFuAGAUFgjIbgBgCMhG7ADJUUjISMhWRshWUQtuAAJLEtTWEVEGyEhWS0AuAAAKwC6AAEABAACKwG6AAUAAgACKwG/AAUAOgAyACkAHgAUAAAACCu/AAYAPwAyACkAHgAUAAAACCsAvwABAEkAQQApAB4AFAAAAAgrvwACAGwAWABFACwAHgAAAAgrvwADAFUAQQA2ACwAFAAAAAgrvwAEABkAFQAQAAwABwAAAAgrALoABwAEAAcruAAAIEV9aRhEAAAAKgCcAGkAhQHJAMMAtAAAABT+VwA0BEQACgWBABsAAAACAI8AAAFpBYEAAwAHACsAuAAARVi4AAIvG7kAAgANPlm4AABFWLgABC8buQAEAAc+WbkABQAB9DAxASMTMwM1MxUBadoQusbMAY0D9Pp/yckAAAACAKEDsgL+BZUAAwAHADcAuAAARVi4AAIvG7kAAgANPlm4AABFWLgABi8buQAGAA0+WbgAAhC5AAAABPS4AATQuAAF0DAxASMDMwEjAzMC5r4W7P53vRfsA7IB4/4dAeMAAAAAAgBO/+wE4AWNABsAHwCbALgAAEVYuAATLxu5ABMADT5ZuAAARVi4ABcvG7kAFwANPlm4AABFWLgABS8buQAFAAc+WbgAAEVYuAAJLxu5AAkABz5ZuwACAAEAAwAEK7sAGQABAAAABCu4AAMQuAAH0LgAAxC4AAvQuAACELgADdC4AAAQuAAP0LgAGRC4ABHQuAAZELgAFdC4AAAQuAAc0LgAAhC4AB3QMDEBAzMVIQMjEyEDIxMjNTMTIzUhEzMDIRMzAzMVIQMhEwPzRf/+4VihVv7IVKBUxeVF9wEWWaFYAThYoVjO/TxHATdFA2H+t5T+aAGY/mgBmJQBSZQBmP5oAZj+aJT+twFJAAMASv9eBLsGAAAkACwAMwEfuwAtAAUADAAEK7sAIgAGAAAABCu7AB8ABQAlAAQruAAAELgABtC4AAAQuAAP0LgAIhC4ABHQuAAiELgAGdBBBQCaACUAqgAlAAJdQRMACQAlABkAJQApACUAOQAlAEkAJQBZACUAaQAlAHkAJQCJACUACV24ACIQuAAp0EETAAYALQAWAC0AJgAtADYALQBGAC0AVgAtAGYALQB2AC0AhgAtAAldQQUAlQAtAKUALQACXbgAABC4ADHQuAAfELgANdwAuAAjL7gAEC+4AABFWLgAAC8buQAAAAc+WbgAAEVYuAAiLxu5ACIABz5ZuwAPAAEAMgAEK7gAABC5AAYAAfS4AA8QuAAS0LgAMhC4ABnQuAAZL7gABhC4ACrQMDElJAM3HgEXES4DNTQ2NzUzFR4BFwcuAScRHgMVFAQHFSMBNC4BJxE+AQEUHgEXEQYCPf5aTdodkmqijlkn8MCurNkx4BdvUKSeXjD/ANCuAaAuWmpqiP2OLVpL0gESAXcvhm8GAcspSWFuTKO7CISECKG5Km1fCP5oJkpeflSt0wujAiw9SzIb/l4GaQLsN0kzEwF1DAAAAAUAeP/gBzUFoQALAA8AGwAnADMBm7sALgAFABkABCu7ABMABQAoAAQruwAiAAUABgAEK7sAAAAFABwABCtBBQCaAAYAqgAGAAJdQRMACQAGABkABgApAAYAOQAGAEkABgBZAAYAaQAGAHkABgCJAAYACV26AA0AGQAAERI5ugAPABkAABESOUETAAYAEwAWABMAJgATADYAEwBGABMAVgATAGYAEwB2ABMAhgATAAldQQUAlQATAKUAEwACXUEFAJoAHACqABwAAl1BEwAJABwAGQAcACkAHAA5ABwASQAcAFkAHABpABwAeQAcAIkAHAAJXUETAAYALgAWAC4AJgAuADYALgBGAC4AVgAuAGYALgB2AC4AhgAuAAldQQUAlQAuAKUALgACXQC4AABFWLgADi8buQAOAA0+WbgAAEVYuAAQLxu5ABAADT5ZuAAARVi4AAMvG7kAAwAHPlm4AABFWLgADC8buQAMAAc+WbsAMQABABYABCu7AAkAAQAfAAQruAADELgADdC4AA0vuAAQELgAD9C4AA8vuAADELkAJQAB9LgAEBC5ACsAAfQwMQEUBiMiJjU0NjMyFgEjATMlMhYVFAYjIiY1NDYBNCYjIgYVFBYzMjYBNCYjIgYVFBYzMjYHNa2sqqqjtbOi+zHTA7TV+7aupKmtramkBVNFSkpJR0pHSvvwRElNSEhLRkkBstz28OLp7vT9VwWpDO/j3vn34OTu/BGvkY6yp5WXAsKtkY+vqZWYAAAAAwBl/9gFhQWdACMALwA5ASq7ADQABQAIAAQruwAqAAUADQAEK7sAEwAFACQABCtBBQCaACQAqgAkAAJdQRMACQAkABkAJAApACQAOQAkAEkAJABZACQAaQAkAHkAJACJACQACV1BEwAGACoAFgAqACYAKgA2ACoARgAqAFYAKgBmACoAdgAqAIYAKgAJXUEFAJUAKgClACoAAl1BEwAGADQAFgA0ACYANAA2ADQARgA0AFYANABmADQAdgA0AIYANAAJXUEFAJUANAClADQAAl0AuAAARVi4ABAvG7kAEAANPlm7ADcAAQAFAAQruAAFELgAANC4AAAvuAAQELkAJwAB9EEFAJkAJwCpACcAAl1BEwAIACcAGAAnACgAJwA4ACcASAAnAFgAJwBoACcAeAAnAIgAJwAJXTAxBSInDgEjIiY1ECUuATU0NjMyFhUUBgcWFzYTFwIHFjMyNxUGATQmIyIGFRQXPgIDJicGFRQWMzI2BN+9bzrKbuL6AVAZMcWzocjA0mWTcD+3RI9OZEJMS/5IVktUVzVpdTlas2/HjXtBcCB0M0nbwAEilC+uSJ2ypIx9wVO6qX0BCDn+89NQGrEeBI1BTlpUbmoqSlL8qNbMVL1KgAsAAAABAJQDngG0BakAAwALALgAAi+4AAAvMDEBIwMhAZrtGQEgA54CCwAAAQBT/joC3QXdAA4AYrsABwAFAA4ABCtBEwAGAAcAFgAHACYABwA2AAcARgAHAFYABwBmAAcAdgAHAIYABwAJXUEFAJUABwClAAcAAl0AuAADL7gAAEVYuAAKLxu5AAoACT5ZugAEAAoAAxESOTAxExoBNxcGAgMQEhcnJgIRUwrIzurdvAqRzuu/nAIeASQBy9AJ5f45/u3+7v4u9wjeAdgBIgABADr+RwLEBeoADgBquwAOAAUABwAEK0EFAJoABwCqAAcAAl1BEwAJAAcAGQAHACkABwA5AAcASQAHAFkABwBpAAcAeQAHAIkABwAJXbgADhC4ABDcALgACi+4AABFWLgAAy8buQADAAk+WboABAADAAoREjkwMQEKAQcnNhITEAInFxYSEQLECsjO6t67CpPM67+cAgb+3P410AnnAcQBFAEUAdL1CN7+KP7eAAAAAAEARAKTA10FlQAOAE4AuAAFL7gABy+4AABFWLgADS8buQANAA0+WboAAAAFAA0REjm6AAMABQANERI5ugAGAAUADRESOboACQAFAA0REjm6AAwABQANERI5MDEBNxcFFwcnByc3JTcFAzMCJP08/u20oY2Tobn+7zsBAQy8BHpjrUf0YvPwYfJHsGcBHAAAAAEAGwCgBDAEsgALAD+7AAEABQACAAQruAACELgABtC4AAEQuAAI0AC4AAcvuAABL7sACQABAAAABCu4AAAQuAAD0LgACRC4AAXQMDEBESMRITUhETMRIRUCiMX+WAGoxQGoAkz+VAGsugGs/lS6AAABAHv+5gGHAO8ACQAmuwABAAUACAAEKwC4AAQvuAAAL7gAAEVYuAAHLxu5AAcABz5ZMDElFRQGByM2NSMRAYcnMLVvWO+8bJJPoWUBAwAAAAEAqwG8AtEChAADAA0AuwABAAEAAAAEKzAxEzUhFasCJgG8yMgAAAABAKsAAAHQAUkAAwAkuwADAAUAAAAEKwC4AABFWLgAAC8buQAAAAc+WbkAAQAE9DAxMxEhEasBJQFJ/rcAAAAAAQAe/9gClQXgAAMACwC4AAAvuAABLzAxFwEzAR4BptH+XigGCPn4AAIAgv/sBFUFlgALABcBObgAGC+4AAwvQQUAmgAMAKoADAACXUETAAkADAAZAAwAKQAMADkADABJAAwAWQAMAGkADAB5AAwAiQAMAAlduQAAAAb0uAAYELgABtC4AAYvuQASAAb0QRMABgASABYAEgAmABIANgASAEYAEgBWABIAZgASAHYAEgCGABIACV1BBQCVABIApQASAAJd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AFYAEQBmABEAdgARAIYAEQAJXUEFAJUAEQClABEAAl24AAAQuAAY3AC4AABFWLgACC8buQAIAAs+WbgAAEVYuAADLxu5AAMABz5ZuAAIELkADgAD9EEFAJkADgCpAA4AAl1BEwAIAA4AGAAOACgADgA4AA4ASAAOAFgADgBoAA4AeAAOAIgADgAJXbgAAxC5ABQABPRBAwAHABQAAV0wMQEQAiMiAhEQITISAzQmIyIGFRQWMzI2BEj67u3yAeX46r2FnZ6Ni5WiiwIe/uT+6gEhARECJv75/vLXub3TnWVeAAAAAAIAmv5XBFEETQARAB4BM7sAAAAGABIABCtBBQCaABIAqgASAAJdQRMACQASABkAEgApABIAOQASAEkAEgBZABIAaQASAHkAEgCJABIACV0AuAAARVi4AA8vG7kADwALPlm4AABFWLgABy8buQAHAAk+WbgAAEVYuAACLxu5AAIABz5ZuQAcAAH0QRMABwAcABcAHAAnABwANwAcAEcAHABXABwAZwAcAHcAHACHABwACV1BBQCWABwApgAcAAJdugAFAAIAHBESOboADAAHAA8REjm4AA8QuQAVAAL0QQUAOQAVAEkAFQACcUEhAAgAFQAYABUAKAAVADgAFQBIABUAWAAVAGgAFQB4ABUAiAAVAJgAFQCoABUAuAAVAMgAFQDYABUA6AAVAPgAFQAQXUEHAAgAFQAYABUAKAAVAANxMDEBECEiJyMUAyMTMwczPgEzMhIHLgEjIg4BFRQWMzI2BFH+cvpWBRDEM7gVBDCegcjGZw2FjXJ8Q5CjjoICIv3KvAr9uQXeqWRd/vTis9Z4rYvBZmEAAAIAO/5XA+kETgAPABsA6rsAFgAGAAMABCtBEwAGABYAFgAWACYAFgA2ABYARgAWAFYAFgBmABYAdgAWAIYAFgAJXUEFAJUAFgClABYAAl0AuAAARVi4AAUvG7kABQALPlm4AABFWLgACS8buQAJAAs+WbgAAEVYuAALLxu5AAsACT5ZuAAARVi4AAAvG7kAAAAHPlm6AAgACwAFERI5uQAZAAT0QQMABwAZAAFdugANAAAAGRESObgABRC5ABMAA/RBBQCZABMAqQATAAJdQRMACAATABgAEwAoABMAOAATAEgAEwBYABMAaAATAHgAEwCIABMACV0wMQUiAhEQITIWFzczAyMT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BZgAIwAtAT24AC4vuAAIL7gALhC4AAPQuAADL7gACBC5ABUABvS4AAgQuAAh0LgAIS+6ACIACAAVERI5uAAIELgAJ9C4AAMQuQAsAAb0QRMABgAsABYALAAmACwANgAsAEYALABWACwAZgAsAHYALACGACwACV1BBQCVACwApQAsAAJduAAVELgAL9wAuAAAL7gAHi+4AABFWLgAEi8buQASAA0+WbsABgACACgABCu4ABIQuQALAAL0QQUAOQALAEkACwACcUEhAAgACwAYAAsAKAALADgACwBIAAsAWAALAGgACwB4AAsAiAALAJgACwCoAAsAuAALAMgACwDYAAsA6AALAPgACwAQXUEHAAgACwAYAAsAKAALAANxuAAeELkAJAAC9LgAGdC4ABkvugAbAAAAEhESOboAIgAAABIREjkwMQEiJjU0Nj8BNTQmIyIGByc+ATMyFhURFBYzMjcVBiMiJicjBicyNj0BBw4BFRQBZ2x+nZuyRlFDUQmVEJ+BkZccIxMYMSJJUQQESZRaf4p2VAKLdGd0fAIEPFFKO0wKanh9ff7MOjIIaA1MQZNvdk9BBAZCQXkAAAIAVwB8BCkDpgAIABEAEwC4AAMvuAAML7gACC+4AAkvMDElATcBFxUJAQclATcBFxUJARUDdP60AQFYqP6nAU4B/YT+tgEBV6b+qwFKfwFzPwFtAx/+kv6LHQsBcz8BbQMf/pL+ix0AAQAnAK4EDQL+AAUAFQC4AAAvuAADL7oAAQAAAAMREjkwMSUTBREhEQLjd/zNA+auAZxaAQ79sAAEAHX/8AYbBZYADwAfAC0ANgHYuwAYAAYACAAEK7sAIwAGACQABCu7ACkABgAuAAQruwAAAAYAEAAEK0EFAJoAEACqABAAAl1BEwAJABAAGQAQACkAEAA5ABAASQAQAFkAEABpABAAeQAQAIkAEAAJXUETAAYAGAAWABgAJgAYADYAGABGABgAVgAYAGYAGAB2ABgAhgAYAAldQQUAlQAYAKUAGAACXboALAAIAAAREjm6AC0ACAAAERI5QQUAmgAuAKoALgACXUETAAkALgAZAC4AKQAuADkALgBJAC4AWQAuAGkALgB5AC4AiQAuAAlduAAjELgAMtAAuAAARVi4AAwvG7kADAANPlm4AABFWLgABC8buQAEAAc+WbsAJgACADEABCu7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AIcABgAJXUEFAJYABgCmAAYAAl24ABQQuQAPAAP0QRMABwAPABcADwAnAA8ANwAPAEcADwBXAA8AZwAPAHcADwCHAA8ACV1BBQCWAA8ApgAPAAJdugARABkABhESOboAFwAZAAYREjm6ABwAFAAPERI5MDETETMRBhYzMjY1ETMRFBYzMjcVBiMiJicGIyImJxGrtQFrcIeStSQqGR1BMFtfBW3BQ20f/lcF4/27iouuogIK/NBMRQiBFF5kwikm/hwAAAABAFX++AQQBYEADwAyugAEAAoAAysAuAABL7gABS+4AABFWLgADS8buQANAA0+WbkAAAAC9LgAA9C4AATQMDEBEyERIxEjEyImNTQ2MyEVA55y/uSy1DOKwsWtAfoFG/ndBiP53QO+uaqpv2YAAAAAAQCrAb4BbgKaAAMAF7sAAwAFAAAABCsAuwABAAEAAAAEKzAxEzUzFavDAb7c3AAAAQBq/k4B1gAAABIAmrsAAAAGAAkABCtBBQCaAAkAqgAJAAJdQRMACQAJABkACQApAAkAOQAJAEkACQBZAAkAaQAJAHkACQCJAAkACV0AuAAARVi4AA4vG7kADgAHPlm4AABFWLgAAi8buQACAAk+WbgAAEVYuAAELxu5AAQACT5ZuwAQAAIACwAEK7gABBC5AAUAAvS4AAfQuAALELgADdC4AA0vMDEFFCEiJzUWMzI1NCMiBzczBx4BAdb+7jkhMSWThSsOQWsnXl79tQRiBlFNArZkA1EAAQB0AjMCoQWBAAoAULsABwAFAAUABCu4AAUQuAAA0LgAAC+4AAcQuQACAAb0ugADAAUABxESOQC4AABFWLgABi8buQAGAA0+WbsAAQACAAAABCu4AAEQuAAI0DAxEzUzEQc1NzMRMxV008rSe9cCM2sCbIp4if0dawAAAAIAgAKLAzgFmAAKABYBH7gAFy+4AAsvQQUAmgALAKoACwACXUETAAkACwAZAAsAKQALADkACwBJAAsAWQALAGkACwB5AAsAiQALAAlduQAAAAb0uAAXELgABtC4AAYvuQARAAb0QRMABgARABYAEQAmABEANgARAEYAEQBWABEAZgARAHYAEQCGABEACV1BBQCVABEApQARAAJduAAAELgAGNwAuAAARVi4AAkvG7kACQANPlm7ABQAAgADAAQruAAJELkADgAC9EEF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IREjETMVITIEBzQmIyERITI2BO1025b+Yr+/AZLvAQLApKT+hQGDmacC34DHb/7XBYH83syGlf3AmwAAAAEAoP/sBKEFzAAxAU27AB8ABgAgAAQruwAsAAYAEgAEK7sAJwAGABgABCtBBQCaABgAqgAYAAJdQRMACQAYABkAGAApABgAOQAYAEkAGABZABgAaQAYAHkAGACJABgACV26AAwAGAAnERI5uAAML0EFAJoADACqAAwAAl1BEwAJAAwAGQAMACkADAA5AAwASQAMAFkADABpAAwAeQAMAIkADAAJXbkAAAAG9LoABgAgAAAREjlBBQCaABIAqgASAAJdQRMACQASABkAEgApABIAOQASAEkAEgBZABIAaQASAHkAEgCJABIACV0AuAAARVi4AB8vG7kAHwAHPlm4AABFWLgAAy8buQADAAc+WbsAJAADABsABCu4AAMQuQAJAAH0QRMABwAJABcACQAnAAkANwAJAEcACQBXAAkAZwAJAHcACQCHAAkACV1BBQCWAAkApgAJAAJdMDEBFAYjIic1HgEzMjY1NCYnLgE1NDY3PgE1NCYjIgYVESMRNDYzMhYVFAcOARUUHgEXFgShvKqrcDKgRVxiVWFcWzk2OjWGbZSLtOvovuFxTyI3UjC4ASeWpTHEHShWT0BmIj6EVj1ULTBUMk1doKL8AwQD4+ahiI9nSDEdJjs5IHz//wB//+wEmQXVACYARAAAAAcAQwDPAAD//wB//+wEmQXkACYARAAAAAcAdAFFAAD//wB//+wEmQXTACYARAAAAAcAwwCDAAD//wB//+wEmQW9ACYARAAAAAcAxQCHAAD//wB//+wEmQV7ACYARAAAAAcAaQDBAAD//wB//+wEmQZzACYARAAAAAcAxADkAAAAAwCO/+wHDgROACcANAA7AW24ADwvuAAoL7kAAAAG9LoADAAoAAAREjm4ADwQuAAS0LgAEi+4ACgQuAAW0LgAEhC5AC0ABvRBEwAGAC0AFgAtACYALQA2AC0ARgAtAFYALQBmAC0AdgAtAIYALQAJXUEFAJUALQClAC0AAl24AAAQuAA70LgAOy8AuAAARVi4ACAvG7kAIAALPlm4AABFWLgAJC8buQAkAAs+WbgAAEVYuAAKLxu5AAoABz5ZuAAARVi4AA8vG7kADwAHPlm7ADsAAwAAAAQruAAKELkABAAD9EETAAcABAAXAAQAJwAEADcABABHAAQAVwAEAGcABAB3AAQAhwAEAAldQQUAlgAEAKYABAACXboADAAKACAREjm4ACAQuQAaAAP0QQUAmQAaAKkAGgACXUETAAgAGgAYABoAKAAaADgAGgBIABoAWAAaAGgAGgB4ABoAiAAaAAlduAA7ELkAKAAC9LgABBC4ADDQuAAaELgAONAwMQEVHgEzMjY3FwIhIAMOASMiJjU0NjczNTQmIyIGBycSITIXNjMgERUlIw4CFRQWMzI+ATUlLgEjIgYHBBQClox1jRmeYf6o/r9mT9KSp6nu8vBveX5xDbwuAY76Y3bkAd38UMOFjUJkXWaZVwL2D5CHf5MGAfcRtb5eSC3/AAEBjHWslq6wBD+Hb1BcEQEki4v9wRgfBzVlSldhWZtWxKudq50AAP//AH7+TgPsBE4AJgBGAAAABwB4ASwAAP//AH//7AQjBdUAJgBIAAAABwBDAPAAAP//AH//7AQjBeQAJgBIAAAABwB0AWEAAP//AH//7AQjBdMAJgBIAAAABwDDAJ4AAP//AH//7AQjBXsAJgBIAAAABwBpAM4AAP//ACMAAAJDBdUAJwDAALgAAAAGAEMAAP//AD0AAAHlBeQAJgDAOwAABgB0AAAAAP//AFkAAALvBdMAJwDAAO8AAAAGAMMAAP//AKsAAALYBXsAJwDAALoAAAAGAGkAAAACAF7/7AQvBeoAGwAnATS4ACgvuAAcL7gAKBC4AAPQuAADL7gAHBC5ABkABfS6AAgAAwAZERI5uAADELkAIgAF9EETAAYAIgAWACIAJgAiADYAIgBGACIAVgAiAGYAIgB2ACIAhgAiAAldQQUAlQAiAKUAIgACXbgAC9C4AAsvugANAAMAGRESOboADwADACIREjm6ABMAHAAZERI5ugAVAAMAGRESObgAGRC4ACncALgAEy+4AABFWLgAAC8buQAAAAc+WbsABgADAB8ABCu6AAgAHwAGERI5ugALAAAAExESOboADQAAABMREjm6AA8AAAATERI5ugAVAAAAExESObgAABC5ACUAA/RBEwAHACUAFwAlACcAJQA3ACUARwAlAFcAJQBnACUAdwAlAIcAJQAJXUEFAJYAJQCmACUAAl0wMQUiAjU0NjMyFyYnBTU3JiczFhclDwEWEh0BEAITNCYjIgYVFBYzMjYCPuj4+O+JXm19/tPabYXRUFoBMgHTq675PI2cnZGQkaGVFAEC8/T+O9lyhXJeV0ckQoRwXJz+augG/vv+8wH1wK2uv76yrwD//wCZAAAERwW9ACYAUQAAAAYAxWoAAAD//wAt/+wD9AXVACYAUqwAAAcAQwDzAAD//wAt/+wD9AXkACYAUqwAAAcAdAFZAAD//wAt/+wD9AXTACYAUqwAAAcAwwCaAAD//wAt/+wD9AW9ACYAUqwAAAcAxQCKAAD//wAt/+wD9AV7ACYAUqwAAAcAaQDRAAAAAwAXAN8D+gR1AAMABwALADu7AAMABgAAAAQruAAAELgACNC4AAMQuAAK0AC7AAkAAQAIAAQruwABAAEAAAAEK7sABQABAAQABCswMQE1MxUBNSEVATUzFQG0qP27A+P9uqgDvre3/qKSkv5/t7cA//8Agf/YBEgF4AAiAFIAAAADABIAxAAA//8Aov/sBC8F1QAmAFgAAAAHAEMAywAA//8Aov/sBC8F5AAmAFgAAAAHAHQBFAAA//8Aov/sBC8F0wAmAFgAAAAGAMNkAAAA//8Aov/sBC8FewAmAFgAAAAHAGkAjwAA//8Aj/5XBIYF5AAmAFwAAAAHAHQBXgAAAAIAq/5XBD4FzAAUACEBXrgAIi+4ABUvuAAiELgAANC4AAAvuQABAAb0uAAE0LgABC9BBQCaABUAqgAVAAJdQRMACQAVABkAFQApABUAOQAVAEkAFQBZABUAaQAVAHkAFQCJABUACV24ABUQuQALAAX0uAABELgAD9C4AA8vugAQAAAAARESObgAARC4ABLQuAABELgAHNC4AAsQuAAj3AC4AAAvuAAARVi4AAgvG7kACAALPlm4AABFWLgAEy8buQATAAk+WbgAAEVYuAANLxu5AA0ABz5ZugAFABMAABESOboAEAATAAAREjm4AAgQuQAYAAP0QQUAmQAYAKkAGAACXUETAAgAGAAYABgAKAAYADgAGABIABgAWAAYAGgAGAB4ABgAiAAYAAlduAANELkAHwAD9EETAAcAHwAXAB8AJwAfADcAHwBHAB8AVwAfAGcAHwB3AB8AhwAfAAldQQUAlgAfAKYAHwACXTAxEzMRFAczPgEzMhIRECEiJyMWFREjATQmIyIOARUUFjMyNqu0BAYwnoHIxv5y+lYFBLQC1nqFa3k/iJmGewXM/llBWGRd/vT+4f3KvAii/lkDx+LCWr+Z1crF//8Aj/5XBIYFewAmAFwAAAAHAGkA4wAAAAEAfgAAAYsEOgADABgAuAABL7gAAEVYuAAALxu5AAAABz5ZMDEzEzMTfi60KwQ6+8YAAAACAIj/9gfNBYwAFAAgAOu4ACEvuAAXL7gAIRC4AAXQuAAFL7gAFxC5ABIABfS4AA3QuAAFELkAHgAF9EETAAYAHgAWAB4AJgAeADYAHgBGAB4AVgAeAGYAHgB2AB4AhgAeAAldQQUAlQAeAKUAHgACXQC4AABFWLgACC8buQAIAA0+WbgAAEVYuAAKLxu5AAoADT5ZuAAARVi4AAAvG7kAAAAHPlm4AABFWLgAAi8buQACAAc+WbsADwABABAABCu4AAoQuQAMAAH0uAAAELkAEgAB9LgAFdC4ABUvuAAX0LgAFy+4AAwQuAAY0LgAGC+4ABvQuAAbLzAxIQYjIAAREAAhMhchFSERIRUhESERATI3ESYiIyICERAEBA5Dj/69/o8BcAFGa2kDkvzdAuf9GQNM+29SNCxJD/X/AQcKAYIBTwFMAXkLnP48mv6L/u4BBwQD4QT+4v71/vS0AAAAAwCS/+wHbgROABoAJQAsAWu4AC0vuAAbL7kAAAAG9LoACwAbAAAREjm4AC0QuAAQ0LgAEC+6ABUAGwAAERI5uQAhAAX0QRMABgAhABYAIQAmACEANgAhAEYAIQBWACEAZgAhAHYAIQCGACEACV1BBQCVACEApQAhAAJduAAAELgALNC4ACwvALgAAEVYuAATLxu5ABMACz5ZuAAARVi4ABcvG7kAFwALPlm4AABFWLgACS8buQAJAAc+WbgAAEVYuAANLxu5AA0ABz5ZuwAsAAEAAAAEK7gACRC5AAMAAfRBEwAHAAMAFwADACcAAwA3AAMARwADAFcAAwBnAAMAdwADAIcAAwAJXUEFAJYAAwCmAAMAAl26AAsACQADERI5ugAVAAkAExESObgAExC5AB4AA/RBBQCZAB4AqQAeAAJdQRMACAAeABgAHgAoAB4AOAAeAEgAHgBYAB4AaAAeAHgAHgCIAB4ACV24AAMQuAAj0LgAHhC4ACnQMDEBHgEXMjY3FwIhICcGISICERASMyAXNiEgAxUlNCYjIgYVECEyNgEuASMiBgcEZgSjjnVeMbJh/qj+7Xl8/uvu+/3yARl1fgEEAd0E/ESKn6OTASqlkAMDDJCHg5kJAjG0pg8uNkD/ALe3ASEBEQEXARmxsf37GBjFu8DA/n67AUhina9QAAAAAQBZBLEC7wXTAAkADwC4AAgvuAABL7gABS8wMQEVIycjByM1EzMC72nbAuho6swExRSpqRQBDgACAHcEkAJbBnMACwAXAKu4ABgvuAAML0EFAJoADACqAAwAAl1BEwAJAAwAGQAMACkADAA5AAwASQAMAFkADABpAAwAeQAMAIkADAAJXbkAAAAG9LgAGBC4AAbQuAAGL7kAEgAG9EETAAYAEgAWABIAJgASADYAEgBGABIAVgASAGYAEgB2ABIAhgASAAldQQUAlQASAKUAEgACXbgAABC4ABncALsAFQACAAMABCu7AAkAAgAPAAQrMDEBFAYjIiY1NDYzMhYHNCYjIgYVFBYzMjYCW45kZI6OZGOPbE44OU5MOzpMBYJkjo5kZYyNZDhOTjg3UlEAAAEAjASxA1kFvQAXACcAuwASAAEAAAAEK7sADQABAAUABCu4AAAQuAAI0LgADRC4ABTQMDEBIi4CIyIGByM+AjMyHgIzMjczDgECjypUTkcfNzYJWwswUT8sVE5FHmQRXBFkBLElLSU+OWZpPSUtJXeUeAAAAQCrAcMFHQJMAAMADQC7AAEAAwAAAAQrMDETNSEVqwRyAcOJiQAAAAEAqwHDCKsCTAADAA0AuwABAAMAAAAEKzAxEzUhFasIAAHDiYkAAAABAIIDuAFLBYEACQAiuwAJAAUAAAAEKwC4AAAvuAAARVi4AAQvG7kABAANPlkwMRM1NDY3MwYVMxWCJSt5X1kDuJJhk0OJfcMAAAAAAQCHA7gBUAWBAAkAJLsAAAAFAAcABCsAuAAARVi4AAgvG7kACAANPlm5AAMABPQwMQEUBgcjNjUjNTMBUCYoe15YwwTwaY9AiHzFAAEAh/76AVAAwwAJACi7AAAABQAHAAQrALgAAEVYuAAGLxu5AAYABz5ZuwAJAAQAAwAEKzAxJRQGByM2NSM1MwFQJih7XljDM2qOQYh+wwAAAgCbA7gCrwWBAAkAEwCFuAAUL7gAAC+5AAkABfS4AAXQuAAFL7gAFBC4AArQuAAKL7kAEwAF9LgAD9C4AA8vuAAJELgAFdwAuAAARVi4AAQvG7kABAANPlm4AABFWLgADi8buQAOAA0+WbsABwABAAkABCu4AAQQuQAAAAT0uAAK0LgABxC4ABHQuAAKELgAE9AwMQE1NDY3MwYVMxUhNTQ2NzMGFTMVAeckKnpeWP3yJSt5X1kDuJJflUOIfsOSYZNDiX3DAAACAJ0DuAKxBYEACQATAJG4ABQvuAAHL7kAAAAF9LgABxC4AATQuAAEL7gAFBC4ABHQuAARL7kACgAF9LgAERC4AA7QuAAOL7gAABC4ABXcALgAAEVYuAAILxu5AAgADT5ZuAAARVi4ABIvG7kAEgANPlm4AAgQuQADAAT0uAAIELkABgAB9LgAAxC4AA3QuAAO0LgABhC4ABDQuAAR0DAxARQGByM2NSM1MwUUBgcjNjUjNTMCsSIteV5Ywv61Jih7XljDBPBdkkmIfsORaY9AiH7DAAIAnf76ArEAwwAJABMAjbgAFC+4AAcvuQAAAAX0uAAHELgABNC4AAQvuAAUELgAEdC4ABEvuQAKAAX0uAARELgADtC4AA4vuAAAELgAFdwAuAAARVi4AAYvG7kABgAHPlm4AABFWLgAEC8buQAQAAc+WbsACQAEAAMABCu4AAYQuQAIAAH0uAADELgADdC4AAgQuAAS0LgAE9AwMSUUBgcjNjUjNTMFFAYHIzY1IzUzArEjLHleWML+tSYoe15YwzNfk0eIfsOQao5BiH7DAAABAHYBgwK0A8AAEQALALgADC+4AAQvMDEBFAcGIyInJjU0NzYzMhYXHgECtFVUenRUU1RTdDlqKiYwAqV0WFZWVXd4UVItJihpAAAAAQAkAI0CHQOsAAgACwC4AAMvuAAALzAxJQE1ATMVCQEVAXT+sAFQp/6xAVGNAW0/AXMf/oz+kR0AAAAAAQCHAI0CgAOsAAgACwC4AAUvuAAALzAxJSM1CQE1MwEVAS+oAVL+sKYBUY0dAW8BdB/+jT8AAAABAAsAAAQNBYEAAwAlALgAAEVYuAACLxu5AAIADT5ZuAAARVi4AAAvG7kAAAAHPlkwMTMjATOflANxkQWBAAAAAgAdAjMCpQWBAAoAEABiuwABAAYAAgAEK7gAARC4AAfQuAACELgAC9C4AAsvuAACELgAD9AAuAABL7gAAEVYuAAGLxu5AAYADT5ZuwAIAAIAAAAEK7gAABC4AAPQugALAAEABhESObgACBC4AA7QMDEBFSM1ITUBMxEzFQMGBwMhEQI2g/5qAYKXb/AVPccBFwLlsrJvAi391XECFyhf/uEBaAABAEv/7ASRBZYAOgE/uwArAAYAFQAEK7gAFRC4ABHQuAARL7gAFRC4ABnQuAAZL7gAKxC4ACbQuAAmL7gAKxC4ACnQuAApL7gAKxC4AC7QuAAuL7gAKxC4ADHQuAAxLwC4AABFWLgAHC8buQAcAA0+WbgAAEVYuAAOLxu5AA4ABz5ZuwAUAAMAEQAEK7sAGQADABYABCu4AA4QuQAAAAH0QRMABwAAABcAAAAnAAAANwAAAEcAAABXAAAAZwAAAHcAAACHAAAACV1BBQCWAAAApgAAAAJduAAcELkAIwAB9EEFAJkAIwCpACMAAl1BEwAIACMAGAAjACgAIwA4ACMASAAjAFgAIwBoACMAeAAjAIgAIwAJXbgAGRC4ACbQugAnAA4AHBESObgAFhC4ACjQuAAUELgALtC6AC8ADgAcERI5uAARELgAMNAwMSUyPgI3PgE9ARcGBwYjIgIDIzczJzcjNzMSNjMyFhcHLgEjIgYHIQchBhUUFhchByEeAxceAwLvGSQeGg4iE+oebm6t2f0eqyh4AwOgKIEg+Nuw2R65DnlqjpcVAb4o/mMDAgIBxCj+bAYYIScVFCowN+wFCQwIEScRBTePVlQBBgEEgU5WfwEB+6ibDltkrrx/GD4UJxOBMUMwJBAQFAoEAAD//wCEAagEeAQKACcAYQAAAOMABwBhAAD/fwAAAAIAeAQ6AwAFegAHABQAXAC4AABFWLgACi8buQAKAAs+WbsABgAEAA4ABCu4AA4QuAAB0LgADhC4AAjQugAJAA4ABhESOboADAAOAAYREjm4AAYQuAAQ0LoAEQAOAAYREjm4AAYQuAAS0DAxARMjEwc1IRUBEwcjJxMjEzMXNzMTAREMQgtuAQcBOA5bNloLRwxIXmFDDAVX/uMBHQUoKP7oAQ/7+/7xAUDY2P7AAAD//wCO/8oEkQXSACIAIAAAAAIAEnDyAAAAAAAAAAAAAAAAACoAXADiAcYC5APSA+YEOASQBNgFEAU4BUwFbAWABkgGkgccB+IILgiCCUYJgAq4C6AL2AwIDCwMTAxsDNoN6g42DswPYg/WEBgQTBEUEVgReBGiEegSDhJiErITbBPIFJIVJhXGFeYWQBZ0Fs4XHBdWF4oXrBfIF+QYBhgaGDIZRBo0GtIbchwaHIAdkB3+HjAeaB6qHswfbh/uIJ4haiIOIkwi3CMuI54j0iQUJFQkwiTsJVQldiXaJhYmMiaoJzwn3ChWKIQpUCmGKrQrlivKK+YtLi1CLfguQi7kL5AvpjBgMJgwsDEcMVoyEDJEMlQyZDJ0MvwzCDMUMyAzLDM4M0QztDPAM8wz2DPkM/Az/DQINBQ0IDQsNDg0RDRQNFw0aDR0NKA0rDS4NMQ00DTcNOg1YjZQNlw2aDZ0NoA2jDaYN6o3tjfCN8432jfmN/I3/jgKOBY48Dj8OQg5FDkgOSw5ODlwOXw5iDmUOaA5rDm4Opw6qDrCO3I8dDyQPQw9Rj1aPW49lD26PeI+Rj6wPxg/Pj9cP3g/mD/qQOJA4kDwQUhBVAAAAAAAAQAACmoAAQG6BgAACARcAAQABf/iAAUABv/2AAYABwBcAAcACAA0AAcAGv/nAAgACQA6AAkACv88AAoAC//0AAsADABgAAwADQBAAA0ADgBwAA4AD/8iAA8AF/6LAA8AGv+hABEAEgBIABEAE//jABEAGf/jABEAGv9dABEAHP/xABIAFP/lABIAFf/rABIAFv/fABIAF/9zABIAGf/FABIAG//fABIAHP/pABIAJP+RABIAJf/xABIAJv+xABIAKv+rABIALf71ABIAMv+/ABIANP+/ABIANf/XABIANv+5ABIARP93ABIARv9/ABIAR//FABIASP99ABIASv+DABIAS//pABIATf+rABIATv/tABIAUP+VABIAUf+VABIAUv97ABIAU/+RABIAVP/HABIAVf+fABIAVv+bABIAWP+zABIAWv/dABIAW//1ABIAXP/FABIAXf/JABMAEf/fABMAEv/VABMAFP/sABMAGv/nABQAFQBIABUAFgAYABYAFwCAABcAGAA0ABcAGv+3ABcAHP/ZABgAGQA2ABkAGgAgABoAD/8lABoAEf8DABoAEv9DABoAE//tABoAF/9nABoAGf/fABoAGwAaABwAEf/hABwAEv/XABwAGv/pABwAHf/sAB4AHwCCAB8AIP/UACAAIf/SACEAIgAYACIAIwAYACMAJP+qACQAIv+3ACQAJQAqACQAJv/NACQAKv/FACQAMv/ZACQANP/ZACQAN/9NACQAOf7xACQAOv9FACQAPP8RACQARv/zACQASP/xACQAUv/vACQAWf+VACQAWv+fACUAEv/zACUAIv/RACUAJgAeACUAN//hACUAOf+HACUAOv+FACUAPP+HACUAXP/vACYAEf/NACYAEv/xACYAJ//aACYAVf/fACYAWP/XACYAXP/DACcAD//DACcAEf+9ACcAEv/DACcAOf+rACcAOv+9ACcAPP+XACgAKQASACgAWf/JACgAWv/BACkAD/61ACkAEf6VACkAEv+bACkAJP/NACkARP+bACkAVf/VACkAWP/ZACkAXP/DACoAEf/jACoAEv/xACoAIv/fACoAK//wACoAS//vACoAUf/rACoAVf/zACoAWP/tACoAXP/ZACwALf/kACwARf/jACwATv/fACwAUP/dACwAUf/dACwAU//VACwAVf/lACwAWP/XACwAXP/jAC0AEf/pAC0ALv/uAC4AIv/PAC4AJv/JAC4AKv/DAC4ALwAUAC4AMv/XAC4ANP/XAC4ASP+/AC4AUv+9AC4AWP+/AC4AWf/dAC4AWv+7AC8AIv+RAC8AJv/pAC8AKv/fAC8AMABgAC8AMv/1AC8AN/9JAC8AOf8BAC8AOv9FAC8APP8TAC8AWv+ZADAAMf/cADEAMv/0ADIAD//NADIAEf/BADIAEv/FADIAM//qADIAN//lADIAOf+rADIAOv+9ADIAPP+XADIATf/vADIAUP/1ADMAD/3LADMAEf23ADMAEv9BADMAFP/nADMAJP9lADMAK//zADMALP/ZADMANACSADMARP+1ADMASP+7ADMAS/+5ADMATP/dADMAUf+1ADMAUv+5ADMAVf+9ADMAVv/ZADMAWP/LADMAXP/XADQADP/ZADQAEf/PADQAEv/RADQANf/iADQAN//bADQAOf+hADQAOv+zADQAPP+PADUAIv/dADUAJv/pADUAKv/jADUANv/gADUAN//FADUAOf9zADUAOv9tADUAPP9zADUAUv/1ADYAEf/vADYAEv/pADYANwAkADYAPP+rADYAUP/vADYAUf/1ADYAU//tADYAWf+9ADYAWv+lADYAXP/lADcAD/8zADcAEP+LADcAEf8NADcAEv9vADcAHf/bADcAHv+zADcAJP+LADcAJv/XADcAKv/TADcAMv/jADcANP/jADcAOABCADcARP9rADcASP91ADcAUP9/ADcAUv9zADcAVf+L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aWVjb2QuZXNMaWNlbnNlZCB1bmRlciB0aGUgU0lMIE9wZW4gRm9udCBMaWNlbnNlLCBWZXJzaW9uIDEuMS4gdGhpcyBsaWNlbnNlIGlzIGF2YWlsYWJsZSB3aXRoIGEgRkFRIGF0OiBodHRwOi8vc2NyaXB0cy5zaWwub3JnL09GTGh0dHA6Ly9zY3JpcHRzLnNpbC5vcmcvT0ZMRXVsZXhpYQBDAG8AcAB5AHIAaQBnAGgAdAAoAGMAKQAgADIAMAAxADIAIABBAGIAZQBsAGEAcgBkAG8AIABHAG8AbgB6AGEAbABlAHoAIAAoAGEAYgBiAGkAZQBAAGEAYgBiAGkAZQBjAG8AZAAuAGUAcwApACwAIAB3AGkAdABoACAAUgBlAHMAZQByAHYAZQBkACAARgBvAG4AdAAgAE4AYQBtAGUAIAAiAEUAdQBsAGUAeABpAGEAIgBFAHUAbABlAHgAaQBhAFIAZQBnAHUAbABhAHIAQQBiAGUAbABhAHIAZABvAEcAbwBuAHoAYQBsAGUAegA6ACAARQB1AGwAZQB4AGkAYQA6ACAAMgAwADEAMgBFAHUAbABlAHgAaQBhAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADAARQB1AGwAZQB4AGkAYQAtAFIAZQBnAHUAbABhAHIARQB1AGwAZQB4AGkAYQAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEEAYgBlAGwAYQByAGQAbwAgAEcAbwBuAHoAYQBsAGUAegAuAEEAYgBlAGwAYQByAGQAbwAgAEcAbwBuAHoAYQBsAGUAegBBAGIAZQBsAGEAcgBkAG8AIABHAG8AbgB6AGEAbABlAHoAYQBiAGIAaQBlAGMAbwBkAC4AZQBzAGEAYgBiAGkAZQBjAG8AZAAuAGUAcwBMAGkAYwBlAG4AcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAFMASQBMACAATwBwAGUAbgAgAEYAbwBuAHQAIABMAGkAYwBlAG4AcwBlACwAIABWAGUAcgBzAGkAbwBuACAAMQAuADEALgAgAHQAaABpAHMAIABsAGkAYwBlAG4AcwBlACAAaQBzACAAYQB2AGEAaQBsAGEAYgBsAGUAIAB3AGkAdABoACAAYQAgAEYAQQBRACAAYQB0ADoAIABoAHQA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
//{{{
/*
* Examplepicture
* A framework for geometric examples with jsxgraph
*
* Petri Salmela (pesalmel@abo.fi)
* Petri Sallasmaa (pekasa@utu.fi)
*
*/
(function($){
// jQuery plugin
$.fn.emathexamplepic = function(options){
// Test for examplepic commands and trigger command with options.
if (typeof(options) === 'string'){
options = {example: options};
// Placeholder variable for returning value.
}
// Extend default settings with user given options.
var settings = $.extend({
xscale: [-6, 6],
yscale: [-6, 6]
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
// Create new Examplepicture object.
var examplepic = new Examplepicture(this, settings);
// Init the examplepicture
examplepic.init();
});
}
var Examplepicture = function(place, settings){
this.place = $(place);
this.settings = settings;
this.place.addClass('examplepicture');
this.xscale = this.settings.xscale || [-6, 6];
this.yscale = this.settings.yscale || [-6, 6];
this.lang = this.settings.lang || this.place.attr('lang') || this.place.parents('[lang]').attr('lang');
}
Examplepicture.prototype.init = function(){
this.drawingNum = -1;
while ($('#examplepicture_'+(++this.drawingNum)).length > 0){};
this.drawingId = 'examplepicture_'+this.drawingNum;
this.place.empty()
.append('<div class="examplepicture_header"></div><div class="examplepicture_drawingarea" id="'+this.drawingId+'"></div><div class="examplepicture_controlarea"></div>');
this.header = this.place.find('.examplepicture_header');
this.drawing = this.place.find('.examplepicture_drawingarea');
this.control = this.place.find('.examplepicture_controlarea');
this.drawing.css({width: '300px', height: '300px'});
if ($('head style#examplepicturecss').length < 1){
$('head').append('<style id="examplepicturecss" type="text/css">'+this.strings.css+'</style>');
}
this.board = JXG.JSXGraph.initBoard(this.drawingId, {
grid: false,
boundingbox: [this.xscale[0], this.yscale[1], this.xscale[1], this.yscale[0]],
keepaspectratio: true,
axis: false,
showNavigation: false,
showCopyright: false
});
if (typeof(this.settings.example) === 'function'){
this.action = this.settings.example;
this.title = exthisample.settings.title || '';
} else if (typeof(this.settings.example) === 'string' && (this.settings.example in this.examples)){
this.action = this.examples[this.settings.example].func;
this.dict = this.examples[this.settings.example].dict;
this.title = this.settings.title || this.localize(this.examples[this.settings.example].title);
} else if (typeof(this.settings.example) === 'object'
&& typeof(this.settings.example.func) == 'function'){
this.action = this.settings.example.func;
this.dict = this.settings.example.dict;
this.title = this.settings.title || this.localize(this.settings.example.title);
}
if (typeof(this.action) === 'function'){
this.setTitle();
this.action();
this.update();
}
}
Examplepicture.prototype.setTitle = function(){
if (typeof(this.title) === 'string' && this.title.length > 0){
this.header.html('<h1>'+this.title+'</h1>');
}
}
Examplepicture.prototype.update = function(){
this.board.update();
}
Examplepicture.prototype.localize = function(text){
var result;
if (this.dict[text]){
if (this.dict[text][this.lang]){
result = this.dict[text][this.lang];
}
result = result || this.dict[text]['en'];
}
result = result || text;
return result;
}
Examplepicture.prototype.examples = {
circleapprox: {
title: 'approximation of pi',
func: function(){
var example = this;
var brd = this.board;
var n = brd.createElement('slider',[[-5,5],[3,5],[3,6,96]],{name:'n',snapWidth:1, precision: 0});
var center = brd.create('point', [0,0], {visible: false});
var rot = brd.create('transform', [function() {return Math.PI*2.0/n.Value();},center], {type:'rotate'});
var ptmp = brd.create('point',[0,0],{visible:false,withLabel:false});
var radius = brd.create('point', [4,0], {visible: false});
var outer = brd.create('curve', [[0],[0]],{fillColor:'#ffff00',highlightFillColor:'#ffff00',fillOpacity:1,highlightFillOpacity:1,strokeColor:'black',highlightStrokeColor:'black'});
var circle = brd.create('circle', [center, radius], {fixed: true, fillColor: '#00ffff',highlightFillcolor: '#00ffff',fillOpacity:0.5,highlightFillOpacity:0.5, strokeColor: 'black', highlightColor:'black'})
var inner = brd.create('curve',[[0,1,2],[0,1,2]],{fillColor:'#ff00ff',highlightFillColor:'#ff00ff',fillOpacity:1,highlightFillOpacity:1,strokeColor:'black',highlightStrokeColor:'black'});
example.control.html('<table><tbody><tr><td>'+ example.localize('value of pi')+':</td><td style="text-align: right;">≈'+(Math.PI).toFixed(5)+'</td></tr><tr class="examplepicture_innerarea"></tr><tr class="examplepicture_outerarea"></tr></tbody></table>');
inner.updateDataArray = function() {
var i, len = n.Value();
this.dataX = [center.X()+circle.getRadius()];
this.dataY = [center.Y()];
ptmp.setPositionDirectly(JXG.COORDS_BY_USER, [center.X()+circle.getRadius(), center.Y()]);
for (i=0;i<len;i++) {
rot.applyOnce(ptmp);
this.dataX.push(ptmp.X());
this.dataY.push(ptmp.Y());
}
example.control.find('.examplepicture_innerarea').html('<td>'+example.localize('approx of pi from inscribed').replace(/%1/,''+n.Value())+':</td><td style="text-align: right;">'+(n.Value()*Math.sin(Math.PI/n.Value())).toFixed(5)+'</td>');
}
outer.updateDataArray = function() {
var i, len = n.Value();
var s = circle.getRadius()/Math.cos(Math.PI/n.Value());
this.dataX = [center.X()+s];
this.dataY = [center.Y()];
ptmp.setPositionDirectly(JXG.COORDS_BY_USER, [center.X()+s,center.Y()]);
for (i=0;i<len;i++) {
rot.applyOnce(ptmp);
this.dataX.push(ptmp.X());
this.dataY.push(ptmp.Y());
}
example.control.find('.examplepicture_outerarea').html('<td>'+example.localize('approx of pi from circumscribed').replace(/%1/,''+n.Value())+':</td><td style="text-align: right;">'+(n.Value()*Math.tan(Math.PI/n.Value())).toFixed(5)+'</td>');
}
},
dict: {
'approximation of pi': {
'en': 'Archimeds\' Approximation of Pi',
'fi': 'Piin likiarvo Arkhimedeen tapaan',
'sv': 'Arkimedes approximation av Pi'
},
'value of pi': {
'en': 'Value of Pi',
'fi': 'Piin arvo',
'sv': 'Pi:s värde'
},
'approx of pi from inscribed': {
'en': 'Inscribed %1-gon',
'fi': 'Sisään piirretystä %1-kulmiosta',
'sv': 'Den inskrivna %1-hörningen'
},
'approx of pi from circumscribed': {
'en': 'Circumscribed %1-gon',
'fi': 'Ympäri piirretystä %1-kulmiosta',
'sv': 'Den omskrivna %1-hörningen'
}
}
},
anglenames: {
title: 'classification of angles',
func: function(){
var example = this;
var brd = this.board;
var radius = 4;
var n = brd.createElement('slider', [[-5.5,5.5],[-5.5,-5],[0,30,360]],{name: 'α', snapWidth: 5, precision: 0});
var center = brd.create('point', [0,0], {visible: true, fixed: true, name: ''});
var point1 = brd.create('point', [radius,0], {visible: false});
var point2 = brd.create('point', [function(){return 4*Math.cos(n.Value()*Math.PI/180);}, function(){return 4*Math.sin(n.Value()*Math.PI/180);}], {visible: false});
var line1 = brd.create('line', [center, point1], {straightFirst: false, straightLast: false})
var line2 = brd.create('line', [center, point2], {straightFirst: false, straightLast: false})
var angle = brd.create('angle', [point1, center, point2], {type: 'sector', orthoType: 'square', orthoSensitivity: 0.5, radius: 0.8, name: 'α'});
point1.update = function(){
var angletext;
if (n.Value() === 0){
angletext = example.localize('zero angle')
} else if (n.Value() < 90) {
angletext = example.localize('acute angle') + ', ' + example.localize('concave angle');
} else if (n.Value() === 90) {
angletext = example.localize('right angle') + ', ' + example.localize('concave angle');
} else if (n.Value() < 180) {
angletext = example.localize('obtuse angle') + ', ' + example.localize('concave angle');
} else if (n.Value() === 180) {
angletext = example.localize('straight angle');
} else if (n.Value() < 360) {
angletext = example.localize('reflex angle');
} else if (n.Value() === 360) {
angletext = example.localize('full angle');
} else {
angletext = example.localize('empty');
}
example.control.html('<p>'+angletext+'</p>');
}
},
dict: {
'and': {
'en': 'and',
'fi': 'ja',
'sv': 'och'
},
'classification of angles': {
'en': 'Classification of angles',
'fi': 'Kulmien luokittelu',
'sv': 'Olika vinklar'
},
'zero angle': {
'en': 'Zero angle',
'fi': 'Nollakulma',
'sv': 'Nollvinkel'
},
'right angle': {
'en': 'Right angle',
'fi': 'Suora kulma',
'sv': 'Rät vinkel'
},
'straight angle': {
'en': 'Straight angle',
'fi': 'Oikokulma',
'sv': 'Rak vinkel'
},
'full angle': {
'en': 'Full angle',
'fi': 'Täysikulma',
'sv': 'Full vinkel'
},
'acute angle': {
'en': 'Acute angle',
'fi': 'Terävä kulma',
'sv': 'Spetsig vinkel'
},
'obtuse angle': {
'en': 'Obtuse angle',
'fi': 'Tylppä kulma',
'sv': 'Trubbig vinkel'
},
'reflex angle': {
'en': 'Reflex angle',
'fi': 'Kupera kulma',
'sv': 'Konvex vinkel'
},
'concave angle': {
'en': 'concave angle',
'fi': 'kovera kulma',
'sv': 'konkav vinkel'
},
'empty': {
'en': ' ',
'fi': ' ',
'sv': ' '
}
}
}
}
Examplepicture.prototype.strings = {
css:
'.examplepicture {margin: 0.5em auto 1em auto; width: 310px; border: 1px solid #999; border-radius: 10px; box-shadow: 0 0 5px rgba(0,0,0,0.5);}'
+'.examplepicture_drawingarea {width: 300px; height: 400px; display: block; border-radius: 5px; border: 1px solid #777; margin: 5px; box-shadow: inset 2px 2px 5px rgba(0,0,0,0.2); background: white;}'
+'.examplepicture_controlarea {margin: 10px 5px;}'
+'.examplepicture_header h1 {margin: 0.2em 0.5em 0.5em 0.5em; padding: 0; font-size: 120%; color: black; border-bottom: 1px solid black;}'
+'.examplepicture_controlarea table {width: 100%; border: none; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;}'
+'.examplepicture_controlarea table tr {border: none;}'
+'.examplepicture_controlarea table td {border: none;}'
+'.examplepicture_controlarea p {margin: 0 0.5em;}'
+'.examplepicture {background: rgb(255,255,255); background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(229,229,229,1) 100%);'
+'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(229,229,229,1)));'
+'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);'
+'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);'
+'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);'
+'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(229,229,229,1) 100%);'
+'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ffffff\', endColorstr=\'#e5e5e5\',GradientType=0 );}'
}
})(jQuery);
if (typeof(config) !== 'undefined' && typeof(config.macros) !== 'undefined'){
// Create macro for TiddlyWiki
config.macros.examplepic = {
/******************************
* Show examplepic
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('Missing examplepic.', place, null, tiddler);
return false;
}
var bookpage = {'pageOne': 0, 'pageTwo': 1}[jQuery(place).parents('.bookpage').attr('id')];
var examplepic = params[0];
var modal = (params[1] === 'modal');
var textparams = (params[2] || '').split('##');
var buttontext = textparams[0];
var booklang = textparams[1] || jQuery(place).attr('lang') || EbookPages[bookpage].currentlang || jQuery(place).parents('[lang]').attr('lang');
var data = DataTiddler.getData(tiddler, 'examplepic', {});
var exampleobj = {example: {}, lang: booklang};
if (data[examplepic]){
exampleobj.example.title = data[examplepic].title;
exampleobj.example.dict = data[examplepic].dict;
exampleobj.example.func = new Function(data[examplepic].func);
} else {
exampleobj = {example: examplepic, lang: booklang};
}
examplepic = exampleobj;
if (modal){
var expictext = '<html><div class="emathexpic-place" lang="'+booklang+'"><a href="javascript:;" class="emathex-button">'+buttontext+'</a></div></html>';
wikify(expictext, place, null, tiddler);
var emexpicbutton = jQuery(place).find('a.emathex-button').last();
emexpicbutton.button({
icons: {
primary: 'em-icon-expic'
}
}).click(function(){
var backdiv = jQuery('<div class="emathexpic-back"></div>');
backdiv.appendTo('body');
backdiv.html('<div class="emexpic-wrapper"></div><a href="javascript:;">x</a>');
backdiv.css({'position': 'fixed', 'top': '0', 'right': '0', 'bottom': '0', 'left': '0', 'background-color': 'rgba(255,255,255,0.9)', 'z-index': '201'});
var closebutton = backdiv.find('a');
closebutton.click(function(){
backdiv.remove();
}).css({'display': 'inline-block', 'position': 'absolute', 'top': '20px', 'right': '20px', 'height': '1.5em', 'width': '1.5em', 'border-radius': '0.4em', 'border': '2px solid black', 'background': '#f00', 'color': 'white', 'text-align': 'center', 'vertical-align': 'middle', 'font-weight': 'bold', 'box-shadow': 'inset 2px 2px 3px rgba(255,255,255,0.5), inset -2px -2px 3px rgba(0,0,0,0.5)'});
var content = backdiv.find('.emexpic-wrapper');
content.css({'max-width': '1000px', 'margin': '5em auto 0 auto'})
.emathexamplepic(examplepic);
});
} else {
var expictext = '<html><div class="emathexpic" lang="'+booklang+'">\n</div></html>';
wikify(expictext, place, null, tiddler);
jQuery(place).find('.emathexpic').last().emathexamplepic(examplepic);
}
return true;
}
}
}
//}}}
!usage
{{{[img[fire_ball.png]]}}}
[img[fire_ball.png]]
!notes
Fire ball image for "flame" theme
!type
image/png
!file
./data/images/fire_ball.png
!url
!data
data:image/png;base64,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
/***
|Name|GeoEditor|
|Version|0.10|
|Author|Rolf Lindén (rolind@utu.fi)|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer, JSXGraph 0.95 or newer, MathQuill, calculator.js.|
|Description|Creates and shows geometric scenes constructed from geometric primitives.|
!!!!!Revisions
<<<
20130425.1003 ''Version 0.10 author alpha''
* Added selection for intersection point visibility.
20130424.1416 ''Version 0.09 author alpha''
* Fixed glider dynamic naming update.
* Added stroke width parameter to line.
20130424.1046 ''Version 0.08 author alpha''
* Added dynamic naming support for point, glider, line and circle.
* Added slope and length property for line.
* Added radius, area and circumference properties for circle.
* Added 'Draw tick labels' to axis properties.
20130404.0902 ''Version 0.07 author alpha''
* Added 'addElement' and 'update' methods to the API. Allows external interaction with the editor.
20130313.1600 ''Version 0.06d author alpha''
* Viewport control is now always visible when editing.
20130312.1632 ''Version 0.06c author alpha''
* Fixed viewport control bug that prevented it's use in edit mode.
* Fixed viewport control bug that allowed clicks to pass the button elements.
20130213.1605 ''Version 0.06b author alpha''
* Gets updated information from text fields even without explicit update.
20130212.1527 ''Version 0.06 author alpha''
* Added setSceneOptions and getSceneOptions to jQuery interface.
20130211.1120 ''Version 0.05 author alpha''
* Added scene controls (no proper GeoScene object support yet).
20130204.1509 ''Version 0.04 author alpha''
* Added GeoAxis object.
* GeoTriangle can now be filled.
* Sped up removal of objects from the scene.
* Changed look for element property view.
20130108.1521 ''Version 0.03b author alpha''
* Fixed a bug related to right angles and naming.
* Fixed multiple bugs related to image captions.
20121219.1133 ''Version 0.03 author alpha''
* 'tabless' mode for captions.
* Image object.
* ParametricCurve -object.
* Point and glider size can be set.
* Angle fill opacity can be set.
*Requires calculator.js and Mathquill from this version onwards.
20121214.1053 ''Version 0.021c author alpha''
*Fixes parallelogram and square naming issues.
20121212.0842 ''Version 0.021 author alpha''
*Adds fill, coloring and dashing for Parallelograms.
<<<
!!!!!Code
***/
//{{{
/**
* Geometry editor (jQuery plugin).
*
* Creates and shows geometric scenes constructed from geometric
* Creates and shows geometric scenes constructed from geometric
* primitives.
*
* Copyright 2012 Rolf Lindén (rolind@utu.fi), all rights reserved.
* No copying for any purposes allowed without written and signed
* authorization.
*
* @version 0.03 author alpha
* @author Rolf Lindén (rolind@utu.fi)
**/
(function ($) {
{ /** CSS & glyphs **/
/** Images needed for editor given in string format **/
var editorImages = {
"controls.png":"url(data:image/png;base64,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);"};
/** CSS needed by editor, given in string format **/
var editorCSS = '.ebookjessiebox {'
+' width: 100%;'
+' height: 500px;'
+' border-bottom: 1px solid black;'
+' background-color: #fff;'
+'}'
+'.ebookjessiebox .nogeocaption {'
+' border-bottom: none !important;'
+' border-radius: 0 !important;'
+'}'
+'.geoItemCaption {'
+' width: 12em;'
+' height: 25px;'
+' margin: 1px;'
+' text-align: right;'
+' padding-right: 4px;'
+' padding-top: 4px;'
+' display: inline-block;'
+' background-color: #f8f8f8;'
+' color: #444;'
+' border: solid 1px gray;'
+' vertical-align: top;'
+' border-radius: 2px;'
+'}'
+'.geoProperty {'
+' min-width: 10em;'
+' min-height: 25px;'
+' margin: 1px;'
+' text-align: left;'
+' padding-right: 4px;'
+' padding-left: 4px;'
+' padding-top: 4px;'
+' display: inline-block;'
+' background-color: #fff;'
+' border: solid 1px gray;'
+' vertical-align: top;'
+' border-radius: 2px;'
+' min-height: 25px;'
+'}'
+'.geoProperty .mathquill-rendered-math {'
+' width: 100%;'
+' height: 100%;'
+' border: none;'
+' margin-right: 10px;'
+'}'
+' .geoProperty .mathquill-editable.hasCursor, .geoProperty .mathquill-editable .hasCursor {'
+' -webkit-box-shadow: none;'
+' -moz-box-shadow: none;'
+' box-shadow: none;'
+' }'
+'.geoProperty input {'
+' width: 100%;'
+' height: 100%;'
+' border: none;'
+' margin-left: 0px;'
+' margin-top: -4px;'
+'}'
+'.geoProperty input[type="checkbox"] {'
//+' width: 100%;'
+' height: 100%;'
+' border: none;'
+' margin-top: 4px;'
+' min-height: 15px;'
+' text-align: left;'
+' display: block;'
+'}'
+'.nogeocaption {'
+' border-bottom: none !important;'
+' border-radius: 0 !important;'
+'}'
+'.ebookjessiebox svg {'
+' width: 100%;'
+' height: 100%;'
+' cursor: crosshair;'
+'}'
+'.invisible {'
+' display: none;'
+'}'
+'.centered {'
+' text-align: center;'
+'}'
+'.geocaption {'
+' display: block;'
+' font-style: italic;'
+' padding: 0.5em 0.8em;'
+' text-align: center;'
+' min-height: 20px;'
+' background-color: #ffa;'
+' border-radius: 0 0 0.5em 0.5em;'
+'}'
+'ul.jessiebuttons {'
+' margin: 0;'
+' padding: 0;'
+' background-color: #ffe;'
+' vertical-align:text-top;'
+'}'
+'ul.jessiebuttons li.jessiebutton.smallBall {'
+' width: 16px;'
+' height: 16px;'
+' margin: 10px 5px 5px 0;'
+' padding: 0;'
+' background-color: inherit;'
+' border: none;'
+' border-radius: 0;'
+' background-position: -16px -224px;'
+'}'
+'ul.jessiebuttons li.jessiebutton.currentjessiebutton.smallBall {'
+' width: 16px;'
+' height: 16px;'
+' background-color: inherit;'
+' margin: 10px 5px 5px 0;'
+' padding: 0;'
+' border-radius: 0;'
+' background-position: -0px -240px;'
+'}'
+'ul.jessiebuttons li.jessiebutton {'
+' display: inline-block;'
+' margin: 0px;'
+' margin-right: -1px;'
+' margin-top: -1px;'
//+' top:-100px;'
+' padding: 0.5em;'
+' padding-top: 0.17em;'
+' padding-bottom: 0.9em;'
+' background-color: #efefef;'
+' color: black;'
+' border: 1px solid black;'
+' border-top: none;'
+' height: 0.5em;'
+' border-radius: 0 0 2px 2px;'
+' cursor: pointer;'
+' text-align: left;'
+' vertical-align:text-top;'
+'}'
+'ul.jessiebuttons li.jessiebutton.currentjessiebutton {'
+' background-color: white;'
+' padding-bottom: 10px;'
+' padding-left:0.8em;'
+' padding-right:0.8em;'
+' padding-bottom:1.2em;'
+'}'
+'.disabled {'
+' color: #ccc !important;'
+' background-color: #ddd !important;'
+'}'
+'.previewBox {'
+' position: relative;'
+' border: 1px solid black;'
+' border-radius: 0 0 0.5em 0.5em;'
+'}'
+'.addTab {'
+' background-color: #2e2;'
+'}'
+'.typeInfoBlock {'
+' display: none;'
+'}'
+'.dataBox {'
+' background-color: #fcc;'
+' overflow: scroll;'
+' height: 300px;'
+' display: none;'
+' font-family: Courier New;'
+' font-size: 10.5pt;'
+'}'
+'.viewportControl {'
+' width: 104px;'
+' height: 80px;'
+' position: absolute;'
+' z-index: 99;'
+' right: 5px;'
+' bottom: 5px;'
+'}'
+'.usesGlyphGraphic {'
+' background-image: '+ editorImages["controls.png"] +';'
+'}'
+'.viewportControlBtn {'
+' width: 32px;'
+' height: 32px;'
+' display: block;'
+' repeat: no-repeat;'
+' position: absolute;'
+' float:left;'
+' cursor: pointer;'
+'}'
+'.toolBtn {'
+' border : solid 1px silver;'
+' margin : 4px;'
+' margin-top: 20px;'
+' border-radius: 2px;'
+' width: 32px;'
+' height: 32px;'
+' display: inline-block;'
+' repeat: no-repeat;'
+' cursor: pointer;'
+'}'
+'.selectedToolBtn {'
+' margin-bottom: 16px !important;'
+' margin-top: 4px !important;'
+' box-shadow: 0px 16px 10px rgba(0, 0, 0, 0.1) !important;'
+'}'
+'.toolBtn:hover {'
+' margin-bottom: 6px;'
+' margin-top: 18px;'
+' box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.2);'
+'}'
+'.leftBtn { background-position: 0px -32px; left: 0px; top: 24px; }'
+'.rightBtn { background-position: 0px -64px; left: 48px; top: 24px;}'
+'.upBtn { background-position: 0px -96px; left: 24px; top: 0px; }'
+'.downBtn { background-position: 0px 0px; left: 24px; top: 48px; }'
+'.zoomInBtn { background-position: 0px -128px; left: 72px; top: 0px; }'
+'.zoomOutBtn { background-position: 0px -160px; left: 72px; top: 48px; }'
+'.angleBtn { background-position: -32px 0px;}'
+'.moveBtn { background-position: -32px -32px;}'
+'.labelBtn { background-position: -32px -64px;}'
+'.sectorBtn { background-position: -32px -96px;}'
+'.regularpolygonBtn { background-position: -32px -128px;}'
+'.associatedlineBtn { background-position: -32px -160px;}'
+'.scriptableBtn { background-position: -32px -192px;}'
+'.pointBtn { background-position: -64px 0px;}'
+'.lineBtn { background-position: -64px -32px;}'
+'.circleBtn { background-position: -64px -64px;}'
+'.triangleBtn { background-position: -64px -96px;}'
+'.gliderBtn { background-position: -64px -128px;}'
+'.squareBtn { background-position: -64px -160px;}'
+'.rectangleBtn { background-position: -64px -192px;}'
+'.parallelogramBtn { background-position: -96px 0px;}'
+'.restrictedtriangleBtn { background-position: -96px -32px;}'
+'.rhombusBtn { background-position: -96px -64px;}'
+'.trapezoidBtn { background-position: -96px -96px;}'
+'.intersectionBtn { background-position: -96px -128px;}'
+'.parametriccurveBtn { background-position: -96px -160px;}'
+'.imageBtn { background-position: -96px -192px;}'
+'.addTabBtn { background-position: -32px -224px !important;}'
+'.nextTabBtn { background-position: -48px -224px !important;}'
+'.prevTabBtn { background-position: -48px -240px !important;}'
+'.axisBtn { background-position: -64px -224px;}'
+'.trashCanBtn {'
+' position: absolute;'
+' right: 3px;'
+' top: -2px;'
+' left: inherit !important;'
+' width: 24px;'
+' height: 24px;'
+' display: block;'
+' repeat: no-repeat;'
+' background-position: 0px -192px;'
+'}';
}
{ /** Editor **/
/**
* Initializes the board to given place with given parameters.
*
* place: Location of the editor.
* params:
* 0: editor mode toggle; true/false.
* 1: Scenes shown in the editor window.
*/
var init = function(place, params) {
// Checks if editor's CSS information is already written to document's head.
if ($('head style#geoeditorstyle').length == 0){
$('head').append('<style id="geoeditorstyle" type="text/css">'+editorCSS+'</style>');
}
var editable = params['editable'];
var dataObj = params['scenes'];
var boxWid = params['width'];
var boxHei = params['height'];
var browsingMode = params['browsingMode'];
var $this = $(place);
$this.data('editable', editable);
{ // Generate the box ID.
// Find the first free box number and create a wrapper for the content.
var boxnum = 0;
while ($('div#ebookjessiebox-' + boxnum).length > 0) boxnum++;
$this.data('boxnum', boxnum);
clearAll(boxnum); // Remove all remains of the old boards that might exist in JSXGraph's memory.
}
{ // Initialize.
var dialog = $(place)
dialog.empty();
dialog.css('width: ' + boxWid);
dialog.css('height: ' + boxHei);
dialog.append('<div id="previewBox-' + boxnum + '" class="previewBox" style="width: ' + boxWid + ';"></div>');
if (editable) {
dialog.append('<div id="contentBox-' + boxnum + '"></div>');
var contentBox = $('div#contentBox-' + boxnum);
{ // Construct part.
contentBox.append('<span title="Move points" class="usesGlyphGraphic toolBtn moveBtn selectedToolBtn"></span>').find(".moveBtn").click(
function() {
$('div#contentBox-' + boxnum).find('span.toolBtn').removeClass('selectedToolBtn');
$(this).addClass('selectedToolBtn');
setTool(boxnum, 'Move');
}
);
for (var i = 0; i < objTypes.length - 2; ++i) {
contentBox.append('<span title="' + objTypes[i] + '" id="createBtn' + i + '" class="usesGlyphGraphic toolBtn ' + objClasses[objTypes[i]].prototype.iconCSS + '"></span>').find('span#createBtn' + i).data('objType', objTypes[i]).click(
function() {
$('div#contentBox-' + boxnum).find('span.selectedToolBtn').removeClass('selectedToolBtn');
$(this).addClass('selectedToolBtn');
setTool(boxnum, $(this).data('objType'));
}
);
}
contentBox.append('<span title="ParametricCurve" class="usesGlyphGraphic toolBtn parametriccurveBtn"></span>').find('span.parametriccurveBtn').click( function() { insertConstruct(boxnum, initNew(boxnum, 'ParametricCurve', null), editable, true); } );
contentBox.append('<span title="Scriptable" class="usesGlyphGraphic toolBtn scriptableBtn"></span>').find('span.scriptableBtn').click( function() { insertConstruct(boxnum, initNew(boxnum, 'Scriptable', null), editable, true); } );
contentBox.append('<p /><div id="constructAccordion"></div>');
contentBox.append('<p /><div id="sceneAccordion"></div>');
}
}
dialog.append('<div id="dataBox-' + boxnum + '" class="dataBox"></div>');
dialog.append('<div id="toolBox-' + boxnum + '" class="dataBox"></div>');
}
$('div#previewBox-' + boxnum).append('<div id="ebookjessiebox-' + boxnum + '" class="ebookjessiebox" style="width: ' + '100%' + '; height: ' + boxHei + ';"></div>').css('width: ' + boxWid);
var sceneArr = new Array();
sceneArr = generateSceneArr(dataObj);
setGeoSceneData(boxnum, sceneArr);
addTabs(boxnum, editable, browsingMode);
$(window).resize(function() { updateScene(boxnum, editable); });
}
var tabClick = function(button, boxnum, editable, browsingMode) { // Tab-click functionality.
// Choose the current tab.
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
if (editable) {
//var idNum = 's' + sceneNum;
//var elements = $('div#contentBox-' + boxnum).find('div#sceneAccordion').eq(0);
//content = elements.find('div#geoScene-' + idNum);
//var s_description = content.find('input#description-' + idNum).val();
//var originalDescription = sceneArr[sceneNum].description;
var caption = $('div#previewBox-' + boxnum).find('#caption-' + boxnum);
if (caption) {
//if (caption.text() == originalDescription) caption.text(s_description);
sceneArr[sceneNum].description = caption.html();
if (browsingMode != 'tabless') $('div#previewBox-' + boxnum).find('.currentjessiebutton').html(caption.text()).attr('title', caption.text());
else $('div#previewBox-' + boxnum).find('.currentjessiebutton').attr('title', caption.text());
setGeoSceneData(boxnum, sceneArr);
}
}
// Update the bounding box.
var bb = getFixedBoundingBox(boxnum);
if (bb != null) sceneArr[sceneNum].boundingBox = bb;
setGeoSceneData(boxnum, sceneArr);
// Get the update the 'current chosen tab' info.
button.parents('div#previewBox-' + boxnum).find('.jessiebutton').removeClass('currentjessiebutton');
button.parents('div#previewBox-' + boxnum).find('.jessiebutton').addClass('disabled');
button.addClass('currentjessiebutton');
var newSceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var parents = button.parents('div#previewBox-' + boxnum);
parents
.find('span#caption-' + boxnum)
.removeClass('invisible geocaption')
.addClass(((sceneArr[0].description.trim() == '') && (!editable)) ? ' invisible' : ' geocaption')
.html(sceneArr[newSceneNum].description);
if ((sceneArr[sceneNum].description.trim() == '') && (!editable))
parents.addClass('nogeocaption');
else
parents.removeClass('nogeocaption');
$('div#contentBox-' + boxnum).find("div#constructAccordion").empty();
setScene(boxnum, parseInt(button.attr('tab')), editable);
}
var addTabs = function(boxnum, editable, browsingMode) { // Add the tab buttons and choose the first tab.
// Generate buttons for the different states below the graph window.
$('div#previewBox-' + boxnum).find('ul.jessiebuttons').remove(); // Remove the old tabs.
if (!editable) $('div#contentBox-' + boxnum).empty();
var jessiebuttons = $('div#ebookjessiebox-' + boxnum).after('<ul class="jessiebuttons' + (browsingMode == 'tabless' ? ' centered' : '') + '"></ul>').empty().next();
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
if (editable || sceneArr.length > 1) {
if (browsingMode == 'tabless') {
jessiebuttons.append('<li class="jessiebutton usesGlyphGraphic smallBall prevTabBtn" tab="<" title="Previous figure."> </li>');
jessiebuttons.find('li.jessiebutton[tab="<"]').click(function() {
var sceneArr = getGeoSceneData(boxnum);
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var nextTab = (sceneNum - 1 + sceneArr.length) % sceneArr.length;
$('div#previewBox-' + boxnum).find('li.jessiebutton[tab="' + nextTab + '"]').click();
});
}
for (var i = 0; i <= sceneArr.length; i++) {
if ( editable && (i == sceneArr.length) ) {
if (browsingMode == 'tabless') {
jessiebuttons.append('<li class="jessiebutton usesGlyphGraphic smallBall addTabBtn addtab" tab="+" title="Add a new tab."> </li>');
}
else {
jessiebuttons.append('<li class="jessiebutton" tab="+" id="addTab" tab="+" title="Add a new tab.">+</li>');
}
// Adds click function for each tab.
jessiebuttons.find('li.jessiebutton[tab="+"]').click(function() {
// Choose the current tab.
var button = jessiebuttons.find('li.jessiebutton[tab="+"]');
// Add a new tab, copy content from the previous tab.
var sceneData = getGeoSceneData(boxnum);
var newObject = jQuery.extend(true, {}, sceneData[sceneData.length - 1]);
sceneData[sceneData.length] = newObject;
sceneData[sceneData.length - 1].description = '' + sceneData.length;
var sceneArr = generateSceneArr(sceneData);
if (browsingMode == 'tabless')
button.before('<li class="jessiebutton usesGlyphGraphic smallBall" tab="' + (sceneArr.length - 1) + '" title="' + sceneArr[sceneArr.length - 1].description + '"> </li>');
else
button.before('<li class="jessiebutton" tab="' + (sceneArr.length - 1) + '">' + sceneArr[sceneArr.length - 1].description + '</li>');
setGeoSceneData(boxnum, sceneArr);
var newBtn = jessiebuttons.find('li.jessiebutton[tab="' + (sceneArr.length - 1) + '"]');
newBtn.click( function () { tabClick($(this), boxnum, editable, browsingMode); });
newBtn.click();
});
} else if (i < sceneArr.length) {
if (browsingMode == 'tabless')
jessiebuttons.append('<li class="jessiebutton' + (i == 0 ? ' currentjessiebutton' : '') + ' usesGlyphGraphic smallBall" tab="' + i + '" title="' + sceneArr[i].description + '"> </li>');
else
jessiebuttons.append('<li class="jessiebutton' + (i == 0 ? ' currentjessiebutton' : '') + '" tab="' + i + '">' + sceneArr[i].description + '</li>');
// Adds click function for each tab.
jessiebuttons.find('li.jessiebutton[tab="' + i + '"]').click( function () { tabClick($(this), boxnum, editable, browsingMode); });
}
if ((i == sceneArr.length) && (browsingMode == 'tabless')) {
jessiebuttons.append('<li class="jessiebutton usesGlyphGraphic smallBall nextTabBtn" tab=">" title="Next figure."> </li>');
jessiebuttons.find('li.jessiebutton[tab=">"]').click(function() {
var sceneArr = getGeoSceneData(boxnum);
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var nextTab = (sceneNum + 1) % sceneArr.length;
$('div#previewBox-' + boxnum).find('ul.jessiebuttons').find('li.jessiebutton[tab="' + nextTab + '"]').click();
});
}
}
}
if (editable || (browsingMode == 'tabless') || sceneArr.length == 1) {
jessiebuttons.after('<span class="currentjessiebutton' + (sceneArr[0].description.trim() == '' ? ' invisible' : ' geocaption') + '" contenteditable="' + editable + '" id="caption-' + boxnum + '" tab="0">' + sceneArr[0].description + '</span>');
if (!editable && sceneArr.length == 1) $('div#previewBox-' + boxnum).find('span.currentjessiebutton').click( function () { tabClick($(this), boxnum, editable, browsingMode); });
$('div#previewBox-' + boxnum).find('span#caption-' + boxnum).bind('keypress.geoeditor', function(event) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if ((keycode == '13')) {
$('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).click();
event.preventDefault();
// Set cursor position.
var el = document.getElementById("caption-" + boxnum);
if (el.innerHTML.trim() != '') {
var range = document.createRange();
var sel = window.getSelection();
range.setStart(el.childNodes[0], el.childNodes[0].length);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
});
}
$('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).click();
}
/**
* As the function name implies, throws the old board away.
*
* boxnum: Index / ID number of the editor.
*/
var clearAll = function(boxnum) {
// Removing the renderer causes an error when freeBoard() is
// used. The renderer has no clear reference in the code.
// Contents of the freeBoard() function is copied below to
// fix the problem.
// Go through the boards and find the right one.
for (var f in JXG.JSXGraph.boards) {
if (JXG.JSXGraph.boards[f].container == 'ebookjessiebox-' + boxnum) {
//JXG.JSXGraph.freeBoard(JXG.JSXGraph.boards[f]);
if (typeof (f) == "string") {
f = JXG.JSXGraph.boards[f]
}
f.removeEventHandlers();
//for (var e in f.objects) {
// f.removeObject(f.objects[e])
//}
for (var d = 0; d < f.containerObj.childNodes.length; d++) {
f.containerObj.removeChild(f.containerObj.childNodes[d])
}
//for (var e in f.objects) {
// delete(f.objects[e])
//}
f.objects = new Object();
//delete(f.renderer);
delete(f.algebra);
delete(JXG.JSXGraph.boards[f.id])
}
}
}
/**
* Occasionally the bounding box is malformed. This function orders the items to correctly.
*
* boxnum : Identifier for the current plot window.
*/
var getFixedBoundingBox = function(boxnum) {
var a;
var board;
for (var p in JXG.JSXGraph.boards)
if (JXG.JSXGraph.boards[p].container == 'ebookjessiebox-' + boxnum) {
board = JXG.JSXGraph.boards[p];
a = board.getBoundingBox();
}
if (typeof a != 'undefined') {
var temp;
if (a[0] > a[2]) {
temp = a[0];
a[0] = a[2];
a[2] = temp;
}
// These need to be inverted as screen coordinates
// increase from top to bottom.
if (a[1] < a[3]) {
temp = a[1];
a[1] = a[3];
a[3] = temp;
}
return a;
} else return null; // No matching board found.
}
/**
* Move the current editor location and update.
*
* boxnum: Index / ID number of the editor.
* dx, dy: Movement difference from current location
* in percentage of respective bounding box dimensions.
*/
var moveOrigin = function(boxnum, dx, dy, editable) {
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var board;
for (var p in JXG.JSXGraph.boards)
if (JXG.JSXGraph.boards[p].container == 'ebookjessiebox-' + boxnum) board = JXG.JSXGraph.boards[p];
var a = getFixedBoundingBox(boxnum);
var jx = Math.abs(a[0] - a[2]) * dx;
var jy = Math.abs(a[1] - a[3]) * dy;
sceneArr[sceneNum].boundingBox[0] += jx;
sceneArr[sceneNum].boundingBox[1] += jy;
sceneArr[sceneNum].boundingBox[2] += jx;
sceneArr[sceneNum].boundingBox[3] += jy;
setGeoSceneData(boxnum, sceneArr);
board.setBoundingBox(sceneArr[sceneNum].boundingBox, true);
if (editable) updateScene(boxnum, editable, true);
}
/**
* Zoom the editor and update.
*
* boxnum: Index / ID number of the editor.
* factor: Zoom factor, in the interval (0, \infty). 1 for no zoom.
* editable: Flag indicating if the editor is in edit mode or not.
*/
var zoom = function(boxnum, factor, editable) {
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var board;
for (var p in JXG.JSXGraph.boards)
if (JXG.JSXGraph.boards[p].container == 'ebookjessiebox-' + boxnum) board = JXG.JSXGraph.boards[p];
var a = getFixedBoundingBox(boxnum);
var jx = Math.abs(a[0] - a[2]) * 0.5;
var jy = Math.abs(a[1] - a[3]) * 0.5;
sceneArr[sceneNum].boundingBox[0] += jx * (1 - factor);
sceneArr[sceneNum].boundingBox[1] += jy * (factor - 1);
sceneArr[sceneNum].boundingBox[2] += jx * (factor - 1);
sceneArr[sceneNum].boundingBox[3] += jy * (1 - factor);
setGeoSceneData(boxnum, sceneArr);
board.setBoundingBox(sceneArr[sceneNum].boundingBox, true);
if (editable) updateScene(boxnum, editable, true);
}
/**
* Selects one of the scenes and shows it in the editor.
*
* boxnum: Index / ID number of the editor.
* sceneNum: Index of the scene that needs to be shown.
* editable: Flag indicating if the editor is in edit mode or not.
*/
var setScene = function(boxnum, sceneNum, editable, refreshFromData) {
if (editable) {
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
for (var i = 0; i < sceneArr[sceneNum].objects.length; ++i) {
insertConstruct(boxnum, sceneArr[sceneNum].objects[i], editable, false, sceneNum, i);
}
var idNum = 's' + sceneNum;
var contentBox = $('div#contentBox-' + boxnum);
var sceneAccordion = contentBox.find('div#sceneAccordion').empty();
sceneAccordion.append(
'<h3 id="' + 'geoSceneHeader' + idNum + '" style="padding-left:40px; height:26px">' +
'<span class="geoObjName">Scene options</span>' +
'</h3>' +
'<div id="' + 'geoScene-' + idNum + '"></div>'
);
var place = sceneAccordion.find('div#geoScene-' + idNum);
//place.append('<span class="geoItemCaption">Name: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" type="text" value="' + sceneArr[sceneNum].name + '" /></span><br/>');
//place.append('<span class="geoItemCaption">Description: </span>' + '<span class="geoProperty"><input id="description-' + idNum + '" size="5" type="text" value="' + sceneArr[sceneNum].description + '" /></span><br/>');
place.append('<span class="geoItemCaption">Show grid: </span>' + '<span class="geoProperty"><input id="showGrid-' + idNum + '" type="checkbox"' + (sceneArr[sceneNum].showGrid ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Static: </span>' + '<span class="geoProperty"><input id="isStatic-' + idNum + '" type="checkbox"' + (sceneArr[sceneNum].isStatic ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Allow controls: </span>' + '<span class="geoProperty"><input id="allowControls-' + idNum + '" type="checkbox"' + (sceneArr[sceneNum].allowControls ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Left bound: </span>' + '<span class="geoProperty"><input id="bboxLeft-' + idNum + '" type="text" size="5" value="' + sceneArr[sceneNum].boundingBox[0] + '"/></span><br/>');
place.append('<span class="geoItemCaption">Top bound: </span>' + '<span class="geoProperty"><input id="bboxTop-' + idNum + '" type="text" size="5" value="' + sceneArr[sceneNum].boundingBox[1] + '"/></span><br/>');
place.append('<span class="geoItemCaption">Right bound: </span>' + '<span class="geoProperty"><input id="bboxRight-' + idNum + '" type="text" size="5" value="' + sceneArr[sceneNum].boundingBox[2] + '"/></span><br/>');
place.append('<span class="geoItemCaption">Bottom bound: </span>' + '<span class="geoProperty"><input id="bboxBottom-' + idNum + '" type="text" size="5" value="' + sceneArr[sceneNum].boundingBox[3] + '"/></span><br/>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
sceneAccordion.accordion('destroy').accordion({active:"h3:last", collapsible: true});
}
updateScene(boxnum, editable, refreshFromData);
}
/**
* Loads the scene data from it's container.
*
* boxnum: Index / ID number of the editor.
*/
var getGeoSceneData = function(boxnum) {
var dataObj = $('div#previewBox-' + boxnum).parent().data('sceneData');
//if ($('div#dataBox-' + boxnum).text().trim() == "") return null;
//return JSON.parse($('div#dataBox-' + boxnum).text());
if (dataObj === undefined) return null;
return dataObj;
}
/**
* Saves the scene data to it's container.
*
* boxnum: Index / ID number of the editor.
* data: The scene object to be saved.
*/
var setGeoSceneData = function(boxnum, data) {
var parent = $('div#previewBox-' + boxnum).parent();
var sendUpdateTrigger = parent.data('sendUpdateTrigger');
var old = parent.data('sceneData');
//var dataObj = $('div#dataBox-' + boxnum).text( JSON.stringify(data) );
if ( sendUpdateTrigger ) {
if (JSON.stringify(old) != JSON.stringify(data)) {
parent.data('sceneData', data);
parent.trigger('geoeditor_changed');
}
}
}
/**
* Event handler function for enter key inside the editor.
*
* event: The key press event.
* boxnum: Index / ID number of the editor.
* editable: Flag indicating if the editor is in edit mode or not.
*/
var enterKeyUpdate = function(event, boxnum, editable) {
var keycode = (event.keyCode ? event.keyCode : event.which);
if ((keycode == '13') || (keycode == '32')) updateScene(boxnum, editable);
}
/**
* Removes a construct from the current scene and
* then updates the view.
*
* boxnum: Index of the applied view.
* objNum: Index of the to-be-removed object.
**/
var removeConstruct = function(boxnum, objNum) {
var tabButton = $('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0);
var sceneNum = parseInt(tabButton.attr('tab'));
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
sceneArr[sceneNum].objects.splice(objNum, 1);
setGeoSceneData(boxnum, sceneArr);
tabButton.click();
}
/**
* Adds the given object to the construct accordion.
*
*
*/
var insertConstruct = function(boxnum, obj, editable, update, sceneNum, idNum) {
var contentBox = $('div#contentBox-' + boxnum);
if (sceneNum == null) sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
if (idNum == null) idNum = getGeoSceneData(boxnum)[sceneNum].objects.length;
var accordion
contentBox.find("#constructAccordion").append(
'<h3 id="' + 'geoConstructHeader' + idNum + '" style="padding-left:40px; height:26px">' +
'<span class="geoObjName">' + obj.name + " (" + obj.type + ')</span>' +
'<span class="typeInfoBlock">' + obj.type + '</span>' +
'<span class="usesGlyphGraphic viewportControlBtn trashCanBtn"></span>' +
'</h3>' +
'<div id="' + 'geoConstruct' + idNum + '"></div>'
);
contentBox.find('h3#' + 'geoConstructHeader' + idNum).find(".trashCanBtn").click(function() { removeConstruct(boxnum, idNum); });
obj.addOptionsDialog(contentBox.find("#constructAccordion").find('div#geoConstruct' + idNum), idNum, boxnum, editable);
if (editable) contentBox.find("#constructAccordion").accordion('destroy').accordion({active:"h3:last", collapsible: true});
if (update) updateScene(boxnum, editable);
}
/**
* Collects object properties from the current scene.
*
* boxnum: Index / ID number of the editor.
*/
var collectScene = function(boxnum) {
var elements = $('div#contentBox-' + boxnum).find('div#constructAccordion').eq(0);
var types = elements.find('h3.ui-accordion-header').find('span.typeInfoBlock');
// Initialize objects.
var objects = [];
for (var i = 0; i < types.length; i++) {
var objType = types.eq(i).text();
content = elements.find('div#geoConstruct' + i);
objects[i] = objClasses[objType].prototype.createFromDialog(content, i);
}
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var idNum = 's' + sceneNum;
var elements = $('div#contentBox-' + boxnum).find('div#sceneAccordion').eq(0);
var types = elements.find('h3.ui-accordion-header').find('span.typeInfoBlock');
var caption = $('div#previewBox-' + boxnum).find('#caption-' + boxnum);
var s_description;
if (caption) {
s_description = caption.html();
}
content = elements.find('div#geoScene-' + idNum);
//var s_name = content.find('input#name-' + idNum).val();
//var s_description = content.find('input#description-' + idNum).val();
var b_showGrid = content.find('input#showGrid-' + idNum).is(':checked');
var b_isStatic = content.find('input#isStatic-' + idNum).is(':checked');
var b_allowControls = content.find('input#allowControls-' + idNum).is(':checked');
var f_bboxLeft = parseFloat(content.find('input#bboxLeft-' + idNum).val());
var f_bboxTop = parseFloat(content.find('input#bboxTop-' + idNum).val());
var f_bboxRight = parseFloat(content.find('input#bboxRight-' + idNum).val());
var f_bboxBottom = parseFloat(content.find('input#bboxBottom-' + idNum).val());
var scene = new GeoScene( {
//'name' : s_name,
'description' : s_description,
'showGrid' : b_showGrid,
'isStatic' : b_isStatic,
'allowControls' : b_allowControls,
'boundingBox' : [f_bboxLeft, f_bboxTop, f_bboxRight, f_bboxBottom],
'objects' : objects
} );
return scene;
}
/**
* Goes through the given GeoScene[] 'sceneArr' and
* returns a script array corresponding to the scenes.
*
* sceneArr: A scene array containing the scripts.
*/
var getScripts = function(sceneArr) {
// Initialize the result.
var result = [];
var s;
// Go through each scene.
for (var i = 0; i < sceneArr.length; i++) {
s = '';
// Go through each object in the scene.
s += sceneArr[i].asJessieScript();
// Add the corresponding script snippet to the scene script.
result[i] = s;
}
return result;
}
/**
* Converts a scene array data object to a scene array.
*
* sceneData: Object to be converted.
*/
var generateSceneArr = function(sceneData) {
var sceneArr = [];
if (sceneData != null) {
for (var i = 0; i < sceneData.length; ++i)
sceneArr[i] = new GeoScene(sceneData[i]);
}
return sceneArr;
}
/**
* Collects the current point data from the editor view and updates
* the new values to the stored scene array.
*
* boxnum: Index / ID number of the editor.
*/
var updateSceneData = function(board, construction, boxnum) {
// Load the scene and determine the current scene number.
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var elements = $('div#contentBox-' + boxnum).find('div#constructAccordion').eq(0);
// Go through each object and update it's information if necessary.
for (var i = 0; i < sceneArr[sceneNum].objects.length; ++i) {
sceneArr[sceneNum].objects[i].updateSceneData(
i,
construction,
elements.find('div#geoConstruct' + i)
);
}
sceneArr[sceneNum].boundingBox = getFixedBoundingBox(boxnum);
setGeoSceneData(boxnum, sceneArr);
}
/**
* Merges the given const
**/
var mergeConstructions = function(c1, c2) {
c1.angles = c1.angles.concat(c2.angles);
c1.circles = c1.circles.concat(c2.circles);
c1.functions = c1.functions.concat(c2.functions);
c1.intersections = c1.intersections.concat(c2.intersections);
c1.macros = c1.macros.concat(c2.macros);
c1.points = c1.points.concat(c2.points);
c1.lines = c1.lines.concat(c2.lines);
c1.polygons = c1.polygons.concat(c2.polygons);
c1.texts = c1.texts.concat(c2.texts);
if ((typeof c1.axes != "undefined") && (typeof c2.axes != "undefined")) c1.axes.concat(c2.axes);
return c1;
}
/**
* Updates all of the visible editor components to match the current
* state of the data object.
*
* boxnum: Index / ID number of the editor.
*/
var updateScene = function(boxnum, editable, refreshFromData) {
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var getMouseCoords = function(e) {
var cPos = board.getCoordsTopLeftCorner(e),
absPos = JXG.getPosition(e),
dx = absPos[0]-cPos[0],
dy = absPos[1]-cPos[1];
return new JXG.Coords(JXG.COORDS_BY_SCREEN, [dx, dy], board);
},
down = function(e) {
e = e || window.event;
var targ = e.target || e.srcElement; // For IE.
if (targ.nodeType == 3) targ = targ.parentNode; // For Safari 3.
if (!$(e.target).hasClass('viewportControlBtn')) { // Only for the editor window.
var coords = getMouseCoords(e);
var tool = generateTool(getGeoToolData(boxnum));
tool.mDown(board, coords, boxnum, editable);
setGeoToolData(boxnum, tool);
}
},
up = function(e) {
e = e || window.event;
var targ = e.target || e.srcElement; // For IE.
if (targ.nodeType == 3) targ = targ.parentNode; // For Safari 3.
if (!$(e.target).hasClass('viewportControlBtn')) { // Only for the editor window.
var coords = getMouseCoords(e);
updateSceneData(board, construction, boxnum);
var tool = generateTool(getGeoToolData(boxnum));
tool.mUp(board, coords, boxnum, editable);
setGeoToolData(boxnum, tool);
}
},
wheel = function (e) {
/*
e = e || window.event;
var dz = e.detail ? e.detail * (-1) : e.wheelDelta / 40;
if (dz > 0) {
zoom(boxnum, Math.pow(1.025, dz), editable)
} else {
zoom(boxnum, Math.pow(0.98, dz), editable)
}
e.preventDefault();
sceneArr[sceneNum].boundingBox = getFixedBoundingBox(boxnum);
setGeoSceneData(boxnum, sceneArr);*/
return false;
};
if (editable) { // Update values from the forms.
//var objects = collectObjects(boxnum);
//sceneArr[sceneNum].objects = objects;
//var originalDescription = sceneArr[sceneNum].description;
if (!refreshFromData) sceneArr[sceneNum] = collectScene(boxnum);
// Update the accordion headings.
var headings = $('div#contentBox-' + boxnum).find('div#constructAccordion').find('h3');
for (var i = 0; i < headings.length; ++i)
headings.eq(i).find('span.geoObjName').text(sceneArr[sceneNum].objects[i].name + " (" + sceneArr[sceneNum].objects[i].type + ")");
}
// Clear the board and redraw the content.
clearAll(boxnum);
var container = $('div#previewBox-' + boxnum).find('div#ebookjessiebox-' + boxnum);
container.empty();
var board = JXG.JSXGraph.initBoard(
'ebookjessiebox-' + boxnum,
{
keepaspectratio:true,
grid:false,
showCopyright:false,
showNavigation:false,
zoom:false/*sceneArr[sceneNum].allowControls && (!sceneArr[sceneNum].isStatic)*/,
pan: (editable || (sceneArr[sceneNum].allowControls && (!sceneArr[sceneNum].isStatic)))
}
);
if (!editable && sceneArr[sceneNum].isStatic) board.removeEventHandlers();
board.suspendUpdate();
{ // View control part.
container.append('<div id="controlBox-' + boxnum + '" class="viewportControl"></div>');
var controlBox = container.find('div#controlBox-' + boxnum);
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn leftBtn" />').find(".leftBtn").click(function() { moveOrigin(boxnum, -0.1, 0, editable); });
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn rightBtn" />').find(".rightBtn").click(function() { moveOrigin(boxnum, 0.1, 0, editable); });
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn upBtn" />').find(".upBtn").click(function() { moveOrigin(boxnum, 0, 0.1, editable); });
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn downBtn" />').find(".downBtn").click(function() { moveOrigin(boxnum, 0, -0.1, editable); });
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn zoomInBtn" />').find(".zoomInBtn").click(function() { zoom(boxnum, 0.8, editable); });
controlBox.append('<span class="usesGlyphGraphic viewportControlBtn zoomOutBtn" />').find(".zoomOutBtn").click(function() { zoom(boxnum, 1.25, editable); });
}
{ // Set the bounding box.
var a = sceneArr[sceneNum].boundingBox;
var temp;
if (a[0] > a[2]) {
temp = a[0];
a[0] = a[2];
a[2] = temp;
}
// These need to be inverted as screen coordinates
// increase from top to bottom.
if (a[1] < a[3]) {
temp = a[1];
a[1] = a[3];
a[3] = temp;
}
board.setBoundingBox(a, true);
// Update the bounding box.
var idNum = 's' + sceneNum;
var contentBox = $('div#contentBox-' + boxnum);
var sceneAccordion = contentBox.find('div#sceneAccordion');
var place = sceneAccordion.find('div#geoScene-' + idNum);
place.find('input#bboxLeft-' + idNum).val(sceneArr[sceneNum].boundingBox[0]);
place.find('input#bboxTop-' + idNum).val(sceneArr[sceneNum].boundingBox[1]);
place.find('input#bboxRight-' + idNum).val(sceneArr[sceneNum].boundingBox[2]);
place.find('input#bboxBottom-' + idNum).val(sceneArr[sceneNum].boundingBox[3]);
}
if (!editable && (sceneArr[sceneNum].isStatic || (!sceneArr[sceneNum].allowControls))) $('div#controlBox-' + boxnum).hide();
else $('div#controlBox-' + boxnum).show();
if (editable || !sceneArr[sceneNum].isStatic) {
board.addHook(up, 'mouseup');
board.addHook(down, 'mousedown');
}
if ( /* Is new (incomplete) zoom mode on? */ false ) {
JXG.removeEvent(board.containerObj, 'mousewheel', board.mouseWheelListener, board);
JXG.removeEvent(board.containerObj, 'DOMMouseScroll', board.mouseWheelListener, board);
JXG.addEvent(board.containerObj, 'mousewheel', wheel, board);
JXG.addEvent(board.containerObj, 'DOMMouseScroll', wheel, board);
}
if (sceneArr[sceneNum].showGrid) board.create('grid', [], {dash : 1}); // According to JXG reference, dash causes lag on iPad, and therefore should not be used there.
var construction = board.construct("");
for (var i = 0; i < sceneArr[sceneNum].objects.length; ++i) {
var obj = sceneArr[sceneNum].objects[i];
var objScript = obj.asJessieScript();
if (objScript.trim() != '') {
var tConstruction = board.construct(objScript);
construction = mergeConstructions(construction, tConstruction);
}
else obj.asConstruct(board, construction);
// Regular polygon point data needs to be updated on the fly, as it is not governed by the editor.
if (obj.type == 'RegularPolygon') {
sceneArr[sceneNum].objects[i] = obj;
var elements = $('div#contentBox-' + boxnum).find('div#constructAccordion').eq(0);
elements.find('div#geoConstruct' + i).find('input#pArr-' + i).val(obj.pArr);
}
}
board.unsuspendUpdate();
if (editable) setGeoSceneData(boxnum, sceneArr);
$('div#previewBox-' + boxnum).find('.jessiebutton').removeClass('disabled');
}
}
{ /** Tools **/
/**
* Constructor
*/
var GeoTool = function(toolData, toolType, state) {
if (toolData == null) {
this.state = state;
this.toolType = toolType;
this.dx = null;
this.dy = null;
this.ux = null;
this.uy = null;
this.temp = null;
} else {
this.state = toolData.state;
this.toolType = toolData.toolType;
this.dx = toolData.dx;
this.dy = toolData.dy;
this.ux = toolData.ux;
this.uy = toolData.uy;
this.temp = toolData.temp;
}
}
/**
* Fetches the current mouse coordinates from the board and stores them
* to the tool memory.
*
* board: The current board.
* coords: Current mouse coordinates.
* boxnum: ID number of the box containing the board.
* editable: Flag that tells if the board is editable or not.
**/
GeoTool.prototype.mDown = function(board, coords, boxnum, editable) {
this.dx = coords.scrCoords[1];
this.dy = coords.scrCoords[2];
}
// Functional copy of GeoTool.prototype.mUp (to be re-written in more efficient way).
GeoTool.prototype.mUp = function(board, coords, boxnum, editable) {
var ready = false;
var bbox = getFixedBoundingBox(boxnum);
var pX = parseInt(coords.usrCoords[1] * 100) / 100;
var pY = parseInt(coords.usrCoords[2] * 100) / 100;
this.ux = coords.scrCoords[1];
this.uy = coords.scrCoords[2];
if ( // point is still in the graph, then create it.
((Math.min(bbox[0], bbox[2]) <= pX) && (pX <= Math.max(bbox[0], bbox[2]))) &&
((Math.min(bbox[1], bbox[3]) <= pY) && (pY <= Math.max(bbox[1], bbox[3]))) &&
(Math.pow(this.dx - this.ux, 2) + Math.pow(this.dy - this.uy, 2) <= 9)
) {
var obj;
if (
(this.toolType == GeoTool.TT_CREATE_SELECT) ||
(this.toolType == GeoTool.TT_CREATE_MOVE)
) {
for (el in board.objects) {
if (
(board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2])) &&
(board.objects[el].name.trim() != "")
) {
/* TODO open the proper accordion tab. */
}
}
}
if (
(this.toolType == GeoTool.TT_CREATE_TRIANGLE) ||
(this.toolType == GeoTool.TT_CREATE_SECTOR) ||
(this.toolType == GeoTool.TT_CREATE_PARALLELOGRAM) ||
(this.toolType == GeoTool.TT_CREATE_TRAPEZOID) ||
(this.toolType == GeoTool.TT_CREATE_ANGLE)
) {
for (el in board.objects) {
if(
JXG.isPoint(board.objects[el]) &&
board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2]) &&
(board.objects[el].name.trim() != "") &&
(board.objects[el].visProp.visible)
) {
// We are over an existing point, use it as part of the new object.
if (this.state == 0) {
this.temp = new Array();
this.temp[0] = board.objects[el].name;
}
else if (this.state == 1) this.temp[1] = board.objects[el].name;
else {
this.temp[2] = board.objects[el].name;
if (this.toolType == GeoTool.TT_CREATE_TRIANGLE) obj = initNew(boxnum, 'Triangle', this);
else if (this.toolType == GeoTool.TT_CREATE_PARALLELOGRAM) obj = initNew(boxnum, 'Parallelogram', this);
else if (this.toolType == GeoTool.TT_CREATE_SECTOR) obj = initNew(boxnum, 'Sector', this);
else if (this.toolType == GeoTool.TT_CREATE_TRAPEZOID) obj = initNew(boxnum, 'Trapezoid', this);
else if (this.toolType == GeoTool.TT_CREATE_ANGLE) obj = initNew(boxnum, 'Angle', this);
ready = true;
}
}
}
// Check that creation went smoothly and move on.
if (typeof this.temp[this.state] != 'undefined') {
++this.state;
this.state = this.state % 3;
}
}
else if (
(this.toolType == GeoTool.TT_CREATE_LINE) ||
(this.toolType == GeoTool.TT_CREATE_AXIS) ||
(this.toolType == GeoTool.TT_CREATE_REGULAR_POLYGON) ||
(this.toolType == GeoTool.TT_CREATE_ASSOCIATED_LINE) ||
(this.toolType == GeoTool.TT_CREATE_CIRCLE) ||
(this.toolType == GeoTool.TT_CREATE_RHOMBUS) ||
(this.toolType == GeoTool.TT_CREATE_RESTRICTED_TRIANGLE) ||
(this.toolType == GeoTool.TT_CREATE_SQUARE) ||
(this.toolType == GeoTool.TT_CREATE_INTERSECTION) ||
(this.toolType == GeoTool.TT_CREATE_RECTANGLE)
) {
for (el in board.objects) {
if (
(
(
JXG.isPoint(board.objects[el]) &&
(
(this.toolType != GeoTool.TT_CREATE_ASSOCIATED_LINE) ||
(this.state == 0)
)
) ||
(
(!JXG.isPoint(board.objects[el])) &&
(
(
(this.toolType == GeoTool.TT_CREATE_INTERSECTION) &&
(
(board.objects[el].elType == 'line') ||
(board.objects[el].elType == 'axis') ||
(board.objects[el].elType == 'parallel') ||
(board.objects[el].elType == 'normal') ||
(board.objects[el].elType == 'circle')
)
) ||
(
(this.toolType == GeoTool.TT_CREATE_ASSOCIATED_LINE) &&
(this.state == 1)
)
)
)
) &&
board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2]) &&
(board.objects[el].name.trim() != "") &&
(board.objects[el].visProp.visible)
) {
// We are over an existing point, use it as part of the new object.
if (this.state == 0) {
this.temp = new Array();
this.temp[0] = board.objects[el].name;
}
else {
this.temp[1] = board.objects[el].name;
if (this.toolType == GeoTool.TT_CREATE_ASSOCIATED_LINE) {
if (board.objects[el].elType == 'line') this.temp[2] = 'Line';
else if (board.objects[el].elType == 'parallel') this.temp[2] = 'Line';
else if (board.objects[el].elType == 'normal') this.temp[2] = 'Line';
else if (board.objects[el].elType == 'axis') this.temp[2] = 'Line';
else if (board.objects[el].elType == 'circle') this.temp[2] = 'Circle';
}
if (this.toolType == GeoTool.TT_CREATE_LINE) obj = initNew(boxnum, 'Line', this);
else if (this.toolType == GeoTool.TT_CREATE_AXIS) obj = initNew(boxnum, 'Axis', this);
else if (this.toolType == GeoTool.TT_CREATE_INTERSECTION) obj = initNew(boxnum, 'Intersection', this);
else if (this.toolType == GeoTool.TT_CREATE_REGULAR_POLYGON) obj = initNew(boxnum, 'RegularPolygon', this);
else if (this.toolType == GeoTool.TT_CREATE_ASSOCIATED_LINE) obj = initNew(boxnum, 'AssociatedLine', this);
else if (this.toolType == GeoTool.TT_CREATE_CIRCLE) obj = initNew(boxnum, 'Circle', this);
else if (this.toolType == GeoTool.TT_CREATE_RHOMBUS) obj = initNew(boxnum, 'Rhombus', this);
else if (this.toolType == GeoTool.TT_CREATE_RESTRICTED_TRIANGLE) obj = initNew(boxnum, 'RestrictedTriangle', this);
else if (this.toolType == GeoTool.TT_CREATE_SQUARE) obj = initNew(boxnum, 'Square', this);
else if (this.toolType == GeoTool.TT_CREATE_RECTANGLE) obj = initNew(boxnum, 'Rectangle', this);
ready = true;
}
}
}
// Check that creation went smoothly and move on.
if (typeof this.temp[this.state] != 'undefined') {
++this.state;
this.state = this.state % 2;
}
}
else if (
(this.toolType == GeoTool.TT_CREATE_POINT) ||
(this.toolType == GeoTool.TT_CREATE_GLIDER) ||
(this.toolType == GeoTool.TT_CREATE_IMAGE) ||
(this.toolType == GeoTool.TT_CREATE_LABEL)
) {
var canCreate = (this.toolType != GeoTool.TT_CREATE_GLIDER) && (this.toolType != GeoTool.TT_CREATE_IMAGE);
var el;
var parent = null;
for (el in board.objects) {
if (this.toolType == GeoTool.TT_CREATE_GLIDER) {
if (
!JXG.isPoint(board.objects[el]) &&
(board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2])) &&
(board.objects[el].name.trim() != "") &&
/* TODO: Bisector and angle should not be interchangable modes due to glider associations. */
((board.objects[el].elType == "curve") || (board.objects[el].elType == "arc") || (board.objects[el].elType == "sector") || (board.objects[el].elType == "normal") || (board.objects[el].elType == "parallel") || (board.objects[el].elType == "axis") || (board.objects[el].elType == "line") || (board.objects[el].elType == "circle") || (board.objects[el].elType == "bisector"))
) {
parent = board.objects[el].name;
canCreate = true;
}
}
else if (this.toolType == GeoTool.TT_CREATE_IMAGE) {
if (JXG.isPoint(board.objects[el]) &&
(board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2])) &&
(board.objects[el].name.trim() != "")
) {
parent = board.objects[el].name;
canCreate = true;
}
} else if (
JXG.isPoint(board.objects[el]) &&
board.objects[el].hasPoint(coords.scrCoords[1], coords.scrCoords[2])
) {
canCreate = false;
break;
}
}
if (canCreate) {
this.temp = new Array();
this.temp[0] = pX;
this.temp[1] = pY;
this.temp[2] = parent;
if (this.toolType == GeoTool.TT_CREATE_POINT) obj = initNew(boxnum, 'Point', this);
else if (this.toolType == GeoTool.TT_CREATE_LABEL) obj = initNew(boxnum, 'Label', this);
else if (this.toolType == GeoTool.TT_CREATE_GLIDER) obj = initNew(boxnum, 'Glider', this);
else if (this.toolType == GeoTool.TT_CREATE_IMAGE) obj = initNew(boxnum, 'Image', this);
ready = true;
};
this.state = 0;
}
if (ready) {
insertConstruct(boxnum, obj, editable, true);
// Added to enable tutorial mode.
$('div#' + board.container).trigger('geoeditor_objectCreated', obj);
}
}
}
GeoTool.prototype.toolTypeStr = function(toolType) {
switch (toolType) {
case 0 : return 'TT_NONE';
case 1 : return 'TT_SELECT';
case 2 : return 'TT_MOVE_POINTS';
case 3 : return 'TT_CREATE_POINT';
case 4 : return 'TT_CREATE_LINE';
case 5 : return 'TT_CREATE_CIRCLE';
case 6 : return 'TT_CREATE_TRIANGLE';
case 7 : return 'TT_CREATE_SCRIPTABLE';
case 8 : return 'TT_CREATE_ANGLE';
case 9 : return 'TT_CREATE_PARALLELOGRAM';
case 10 : return 'TT_CREATE_LABEL';
case 11 : return 'TT_CREATE_RHOMBUS';
case 12 : return 'TT_CREATE_TRAPEZOID';
case 13 : return 'TT_CREATE_RECTANGLE';
case 14 : return 'TT_CREATE_GLIDER';
case 15 : return 'TT_CREATE_ASSOCIATED_LINE';
case 16 : return 'TT_CREATE_REGULAR_POLYGON';
case 17 : return 'TT_CREATE_POLYGON';
case 18 : return 'TT_CREATE_SQUARE';
case 19 : return 'TT_CREATE_RESTRICTED_TRIANGLE';
case 20 : return 'TT_CREATE_SECTOR';
case 21 : return 'TT_CREATE_INTERSECTION';
case 22 : return 'TT_CREATE_PARAMETRIC_CURVE';
case 23 : return 'TT_CREATE_IMAGE';
case 24 : return 'TT_CREATE_AXIS';
default : return 'Unknown tool type';
}
}
{ // Constants for tool types.
GeoTool.TT_NONE = 0;
GeoTool.TT_SELECT = 1;
GeoTool.TT_MOVE_POINTS = 2;
GeoTool.TT_CREATE_POINT = 3;
GeoTool.TT_CREATE_LINE = 4;
GeoTool.TT_CREATE_CIRCLE = 5;
GeoTool.TT_CREATE_TRIANGLE = 6;
GeoTool.TT_CREATE_SCRIPTABLE = 7;
GeoTool.TT_CREATE_ANGLE = 8;
GeoTool.TT_CREATE_PARALLELOGRAM = 9;
GeoTool.TT_CREATE_LABEL = 10;
GeoTool.TT_CREATE_RHOMBUS = 11;
GeoTool.TT_CREATE_TRAPEZOID = 12;
GeoTool.TT_CREATE_RECTANGLE = 13;
GeoTool.TT_CREATE_GLIDER = 14;
GeoTool.TT_CREATE_ASSOCIATED_LINE = 15;
GeoTool.TT_CREATE_REGULAR_POLYGON = 16;
GeoTool.TT_CREATE_POLYGON = 17;
GeoTool.TT_CREATE_SQUARE = 18;
GeoTool.TT_CREATE_RESTRICTED_TRIANGLE = 19;
GeoTool.TT_CREATE_SECTOR = 20;
GeoTool.TT_CREATE_INTERSECTION = 21;
GeoTool.TT_CREATE_PARAMETRIC_CURVE = 22;
GeoTool.TT_CREATE_IMAGE = 23;
GeoTool.TT_CREATE_AXIS = 24;
}
var generateTool = function(toolData) {
return new GeoTool(toolData, GeoTool.TT_NONE, 0);
}
var setTool = function(boxnum, type) {
var tool = generateTool(getGeoToolData(boxnum));
tool.state = 0;
switch (type) {
case 'None' : tool.toolType = GeoTool.TT_NONE; break;
case 'Move' : tool.toolType = GeoTool.TT_MOVE_POINTS; break;
case 'Point' : tool.toolType = GeoTool.TT_CREATE_POINT; break;
case 'Line' : tool.toolType = GeoTool.TT_CREATE_LINE; break;
case 'Axis' : tool.toolType = GeoTool.TT_CREATE_AXIS; break;
case 'Circle' : tool.toolType = GeoTool.TT_CREATE_CIRCLE; break;
case 'Triangle' : tool.toolType = GeoTool.TT_CREATE_TRIANGLE; break;
case 'Angle' : tool.toolType = GeoTool.TT_CREATE_ANGLE; break;
case 'Parallelogram' : tool.toolType = GeoTool.TT_CREATE_PARALLELOGRAM; break;
case 'Label' : tool.toolType = GeoTool.TT_CREATE_LABEL; break;
case 'Rhombus' : tool.toolType = GeoTool.TT_CREATE_RHOMBUS; break;
case 'Trapezoid' : tool.toolType = GeoTool.TT_CREATE_TRAPEZOID; break;
case 'Rectangle' : tool.toolType = GeoTool.TT_CREATE_RECTANGLE; break;
case 'Glider' : tool.toolType = GeoTool.TT_CREATE_GLIDER; break;
case 'AssociatedLine' : tool.toolType = GeoTool.TT_CREATE_ASSOCIATED_LINE; break;
case 'RegularPolygon' : tool.toolType = GeoTool.TT_CREATE_REGULAR_POLYGON; break;
case 'Polygon' : tool.toolType = GeoTool.TT_CREATE_POLYGON; break;
case 'Square' : tool.toolType = GeoTool.TT_CREATE_SQUARE; break;
case 'RestrictedTriangle' : tool.toolType = GeoTool.TT_CREATE_RESTRICTED_TRIANGLE; break;
case 'Sector' : tool.toolType = GeoTool.TT_CREATE_SECTOR; break;
case 'Intersection' : tool.toolType = GeoTool.TT_CREATE_INTERSECTION; break;
case 'Image' : tool.toolType = GeoTool.TT_CREATE_IMAGE; break;
case 'ParametricCurve' : tool.toolType = GeoTool.TT_CREATE_PARAMETRIC_CURVE; break;
case 'Scriptable' : tool.toolType = GeoTool.TT_CREATE_SCRIPTABLE; break;
}
setGeoToolData(boxnum, tool);
}
/**
* Loads the tool data from it's container.
*
* boxnum: Index / ID number of the editor.
*/
var getGeoToolData = function(boxnum) {
if ($('div#toolBox-' + boxnum).text().trim() == "") return null;
return JSON.parse($('div#toolBox-' + boxnum).text());
}
/**
* Saves the tool data to it's container.
*
* boxnum: Index / ID number of the editor.
* data: The tool object to be saved.
*/
var setGeoToolData = function(boxnum, data) {
$('div#toolBox-' + boxnum).text(JSON.stringify(data));
}
var fetchNext = function(nextID) {
if (nextID.substring(nextID.length - 1, nextID.length) == "Z")
nextID = nextID.substring(0, nextID.length - 1) + 'AA';
else
nextID = nextID.substring(0, nextID.length - 1) +
String.fromCharCode(nextID.charCodeAt(nextID.length - 1) + 1);
return nextID;
}
var getNextFreePointId = function(sceneArr, sceneNum, initialValue) {
var nextID = initialValue;
var i = 0;
var startOver = false;
while (i < sceneArr[sceneNum].objects.length) {
if ( (sceneArr[sceneNum].objects[i].type == 'Point') ||
(sceneArr[sceneNum].objects[i].type == 'Glider') ) {
if (sceneArr[sceneNum].objects[i].name == nextID) {
nextID = fetchNext(nextID);
startOver = true;
}
}
else if (sceneArr[sceneNum].objects[i].type == 'RegularPolygon') {
// Only the points in the middle are interresting.
for (var j = 2; j < sceneArr[sceneNum].objects[i].pArr.length - 1; ++j )
if (sceneArr[sceneNum].objects[i].pArr[j] == nextID) {
nextID = fetchNext(nextID);
startOver = true;
}
}
if (startOver) {
i = 0;
startOver = false;
}
else ++i;
}
return nextID;
}
/**
* Creates a new element of defined type with default values.
*
* boxnum: Index / ID number of the editor.
* typeStr: Type of the object. Possible values are
* Point, Line, Circle, Triangle and Scriptable.
*/
var initNew = function(boxnum, typeStr, initParams) {
var sceneNum = parseInt($('#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
var sceneArr = generateSceneArr(getGeoSceneData(boxnum));
switch (typeStr) {
case 'Glider' :
case 'Point' : {
var nextID = getNextFreePointId(sceneArr, sceneNum, 'A');
if (typeStr == 'Point') return new GeoPoint({ 'x': initParams.temp[0], 'y': initParams.temp[1], 'name': nextID});
else if (typeStr == 'Glider') return new GeoGlider({ 'parent' : initParams.temp[2], 'x' : initParams.temp[0], 'y' : initParams.temp[1], 'name' : nextID });
}
default : {
var count = 0;
var angleNames = ["alpha", "beta", "gamma", "delta",
"epsilon", "zeta", "eta", "theta", "iota", "kappa",
"lambda", "mu", "nu", "xi", "omicron", "pi", "rho",
"sigmaf", "sigma", "tau", "upsilon", "phi", "chi",
"psi", "omega"];
for (var i = 0; i < sceneArr[sceneNum].objects.length; ++i )
if (sceneArr[sceneNum].objects[i].type == typeStr) ++count;
if (typeStr == 'Line') return new GeoLine({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'l' + initParams.temp[0] + initParams.temp[1] });
else if (typeStr == 'Axis') return new GeoAxis({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'axis' + (count + 1) });
else if (typeStr == 'Image') return new GeoImage({ 'p1' : initParams.temp[2], 'name' : 'img' + (count + 1) });
else if (typeStr == 'Intersection') return new GeoIntersection({ 'o1' : initParams.temp[0], 'o2' : initParams.temp[1], 'name' : 'i' + (count + 1) });
else if (typeStr == 'RegularPolygon') return new GeoRegularPolygon({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'v' + (count + 1) });
else if (typeStr == 'Square') return new GeoSquare({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'sqr' + (count + 1) });
else if (typeStr == 'AssociatedLine') return new GeoAssociatedLine({'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'a' + (count + 1), 'p2Type' : initParams.temp[2] });
else if (typeStr == 'Circle') return new GeoCircle({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'c' + (count + 1) });
else if (typeStr == 'Triangle') return new GeoTriangle({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'p3' : initParams.temp[2], 'name' : 't' + (count + 1) });
else if (typeStr == 'Sector') return new GeoSector({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'p3' : initParams.temp[2], 'name' : 'se' + (count + 1) });
else if (typeStr == 'RestrictedTriangle') return new GeoRestrictedTriangle({'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'rt' + (count + 1) });
else if (typeStr == 'Angle') return new GeoAngle({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'p3' : initParams.temp[2], 'name' : '&' + angleNames[count] + ';' });
else if (typeStr == 'Parallelogram') return new GeoParallelogram({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'p3' : initParams.temp[2], 'name' : 'q' + (count + 1) });
else if (typeStr == 'Label') return new GeoLabel({ 'x' : initParams.temp[0], 'y' : initParams.temp[1], 'name' : 'Label ' + (count + 1) });
else if (typeStr == 'Rhombus') return new GeoRhombus({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'r' + (count + 1) });
else if (typeStr == 'Trapezoid') return new GeoTrapezoid({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'p3' : initParams.temp[2], 'name' : 'u' + (count + 1) });
else if (typeStr == 'Rectangle') return new GeoRectangle({ 'p1' : initParams.temp[0], 'p2' : initParams.temp[1], 'name' : 'o' + (count + 1) });
else if (typeStr == 'ParametricCurve') return new GeoParametricCurve({ 'name' : 'Curve ' + (count + 1) });
else if (typeStr == 'Scriptable') return new GeoScriptable({ 'name' : 'Script ' + (count + 1) });
else return null;
}
}
}
}
{ /** Data objects **/
{ // GeoPoint
/**
* Constructor for geometric point object.
*/
var GeoPoint = function(params) {
params = $.extend( {
'x' : null,
'y' : null,
'name' : null,
'showName' : true,
'visible' : true,
'fixed' : false,
'size' : 3,
'color' : '#f00'
}, params);
this.type = 'Point';
this.size = params.size;
this.x = params.x;
this.y = params.y;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.color = params.color;
}
GeoPoint.prototype.nameStr = function(construction) {
if (this.showName) {
var result = this.name;
for (var property in this) {
result = result.replace(new RegExp('%' + property + '%', 'g'), this[property]);
}
return result;
} else return '';
}
/**
* CSS style defining the icon representing this type.
**/
GeoPoint.prototype.iconCSS = 'pointBtn';
GeoPoint.prototype.updateSceneData = function(index, construction, content) {
// Update values to scene array.
var p = findPointByName(this.name, construction);
// Two decimal precision.
var newX = parseInt(p.coords.usrCoords[1] * 100) / 100;
var newY = parseInt(p.coords.usrCoords[2] * 100) / 100;
this.x = (typeof(this.x == 'number') ? newX : this.x);
this.y = (typeof(this.y == 'number') ? newY : this.y);
if (this.showName) p.label.content.setText(this.nameStr(construction));
// Update values to construct accordion.
content.find('input#xCoordinate-' + index).val(newX);
content.find('input#yCoordinate-' + index).val(newY);
}
/**
* Convert a GeoPoint to JessieScript.
*/
GeoPoint.prototype.asJessieScript = function() { /* Not used. */ return ""; }
GeoPoint.prototype.asConstruct = function(board, construction) {
var obj = this;
var p = board.create(
'point',
[this.x, this.y],
{
name : this.name,
size : this.size,
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
strokeColor: (!this.fixed ? this.color : '#000'),
fillColor: (!this.fixed ? this.color : '#000')
}
);
p.obj = obj;
construction.points.push(p);
construction[this.name] = p;
if (this.showName) p.label.content.setText(this.nameStr(construction));
}
GeoPoint.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
var s =
'<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" type="text" size="5" value="' + this.name + '"/></span><br/>' +
'<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Fixed: </span>' + '<span class="geoProperty"><input id="fixed-' + idNum + '" type="checkbox"' + (this.fixed ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Size: </span>' + '<span class="geoProperty"><input id="size-' + idNum + '" type="text" size="5" value="' + this.size + '"/></span><br/>' +
'<span class="geoItemCaption">x-coordinate: </span>' + '<span class="geoProperty"><input id="xCoordinate-' + idNum + '" type="text" size="5" value="' + this.x + '"/></span><br/>' +
'<span class="geoItemCaption">y-coordinate: </span>' + '<span class="geoProperty"><input id="yCoordinate-' + idNum + '" type="text" size="5" value="' + this.y + '"/></span><br/>';
place.append(s);
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.find('input').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
//enterKeyUpdate = function(event, boxnum, editable) {
}
GeoPoint.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var fixed = content.find('input#fixed-' + idNum).is(':checked');
var size = parseFloat(content.find('input#size-' + idNum).val());
var x = parseFloat(content.find('input#xCoordinate-' + idNum).val());
var y = parseFloat(content.find('input#yCoordinate-' + idNum).val());
if (isNaN(x)) x = content.find('input#xCoordinate-' + idNum).val();
if (isNaN(y)) y = content.find('input#yCoordinate-' + idNum).val();
var color = content.find('input#color-' + idNum).val();
return new GeoPoint({'x' : x, 'y' : y, 'size' : size, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'fixed' : fixed, 'color' : color});
}
}
{ // GeoImage
/**
* Constructor for geometric point object.
*/
var GeoImage = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'offsetX' : 0,
'offsetY' : 0,
'width' : 1,
'height' : 1,
'name' : null,
'showName' : true,
'visible' : true,
'fixed' : false,
'path' : '',
'opacity' : 1.0
}, params);
this.type = 'Image';
this.p1 = params.p1;
this.p2 = params.p2;
this.width = params.width;
this.height = params.height;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.fixed = params.fixed;
this.path = params.path;
this.offsetX = params.offsetX;
this.offsetY = params.offsetY;
this.opacity = params.opacity;
}
/**
* CSS style defining the icon representing this type.
**/
GeoImage.prototype.iconCSS = 'imageBtn';
GeoImage.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoPoint to JessieScript.
*/
GeoImage.prototype.asJessieScript = function() { /* Not used. */ return ""; }
GeoImage.prototype.asConstruct = function(board, construction) {
var p = findPointByName(this.p1, construction);
var parent = this;
var img = board.create(
'image',
[this.path, [function(){return p.X() + parent.offsetX;},function(){return p.Y() + parent.offsetY;}], [this.width, this.height]],
{
name : this.name,
withLabel : this.showName,
visible : this.visible,
fixed : this.fixed,
fillOpacity : this.opacity,
strokeOpacity : this.opacity,
layer : 4
}
);
//construction.images.push(p);
//construction[this.name] = p;
}
GeoImage.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
var s =
'<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" type="text" size="5" value="' + this.name + '"/></span><br/>' +
'<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Fixed: </span>' + '<span class="geoProperty"><input id="fixed-' + idNum + '" type="checkbox"' + (this.fixed ? ' checked="checked" ': '') + '/></span><br/>' +
'<span class="geoItemCaption">Image origin: </span>' + '<span class="geoProperty"><input id="p1-' + idNum + '" type="text" size="5" value="' + this.p1 + '"/></span><br/>' +
'<span class="geoItemCaption">Width: </span>' + '<span class="geoProperty"><input id="width-' + idNum + '" type="text" size="5" value="' + this.width + '"/></span><br/>' +
'<span class="geoItemCaption">Height: </span>' + '<span class="geoProperty"><input id="height-' + idNum + '" type="text" size="5" value="' + this.height + '"/></span><br/>' +
'<span class="geoItemCaption">x-offset: </span>' + '<span class="geoProperty"><input id="offsetX-' + idNum + '" type="text" size="5" value="' + this.offsetX + '"/></span><br/>' +
'<span class="geoItemCaption">y-offset: </span>' + '<span class="geoProperty"><input id="offsetY-' + idNum + '" type="text" size="5" value="' + this.offsetY + '"/></span><br/>' +
'<span class="geoItemCaption">Opacity: </span>' + '<span class="geoProperty"><input id="opacity-' + idNum + '" type="text" size="5" value="' + this.opacity + '"/></span><br/>' +
'<span class="geoItemCaption">Path: </span>' + '<span class="geoProperty"><input id="path-' + idNum + '" type="text" size="8" value="' + this.path + '"/></span><br/>';
place.append(s);
place.find('input').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
//enterKeyUpdate = function(event, boxnum, editable) {
}
GeoImage.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var fixed = content.find('input#fixed-' + idNum).is(':checked');
var p1 = content.find('input#p1-' + idNum).val();
var offsetX = parseFloat(content.find('input#offsetX-' + idNum).val());
var offsetY = parseFloat(content.find('input#offsetY-' + idNum).val());
var width = parseFloat(content.find('input#width-' + idNum).val());
var height = parseFloat(content.find('input#height-' + idNum).val());
var opacity = parseFloat(content.find('input#opacity-' + idNum).val());
var path = content.find('input#path-' + idNum).val();
return new GeoImage({'p1' : p1, 'width' : width, 'height' : height, 'offsetX' : offsetX, 'offsetY' : offsetY, 'opacity' : opacity, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'fixed' : fixed, 'path' : path});
}
}
{ // GeoLine
/**
* Constructor for geometric line object.
*/
var GeoLine = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'firstArrow' : false,
'lastArrow' : false,
'name' : null,
'dash' : 0,
'lineType' : 'lineSegment',
'showName' : true,
'visible' : true,
'color' : '#00f',
'strokeWidth' : 2,
'labelOffset' : [10, 10]
}, params);
this.type = 'Line';
this.p1 = params.p1;
this.p2 = params.p2;
this.strokeWidth = params.strokeWidth;
this.firstArrow = params.firstArrow;
this.lastArrow = params.lastArrow;
this.name = params.name;
this.dash = params.dash;
this.lineType = params.lineType;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
this.labelOffset = params.labelOffset;
}
GeoLine.prototype.nameStr = function(construction) {
if (this.showName) {
var result = this.name;
for (var property in this) {
result = result.replace(new RegExp('%' + property + '%', 'g'), this[property]);
}
return result;
} else return '';
}
/**
* CSS style defining the icon representing this type.
**/
GeoLine.prototype.iconCSS = 'lineBtn';
GeoLine.prototype.updateSceneData = function(index, construction, content) {
var point1 = findPointByName(this.p1, construction);
var point2 = findPointByName(this.p2, construction);
this.length = Math.round(Math.sqrt( Math.pow(point1.X() - point2.X(), 2) + Math.pow(point1.Y() - point2.Y(), 2) ) * 100) / 100;
if (Math.abs(point1.X() - point2.X()) >= 0.00001)
this.slope = Math.round(( ( point2.Y() - point1.Y() ) / (point2.X() - point1.X()) ) * 100) / 100;
else this.slope = '?';
var p = findPointByName('labelOf' + this.name, construction);
if (this.showName) p.label.content.setText(this.nameStr(construction));
}
/**
* Convert a GeoLine to JessieScript.
*/
GeoLine.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoLine.prototype.asConstruct = function(board, construction) {
var line = board.create(
'line',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
withLabel : false,
straightFirst : ((this.lineType == 'line') || (this.lineType == 'startingLine')),
straightLast : ((this.lineType == 'line') || (this.lineType == 'endingLine')),
firstArrow : this.firstArrow,
lastArrow : this.lastArrow,
dash : this.dash,
strokeWidth : this.strokeWidth,
color : this.color,
label : {
fixed : false
}
}
);
var labelPoint = board.create(
'point',
[
function (){ return ((line.point1.X() + line.point2.X()) / 2); },
function (){ return ((line.point1.Y() + line.point2.Y()) / 2); }
],
{
// Options here.
visible : this.visible,
fixed : true,
name : 'labelOf' + this.name,
withLabel : this.showName,
isLabel : true,
size : -1,
label : {
offset : this.labelOffset,
fixed : false
}
}
);
construction.points.push(labelPoint);
construction['labelOf' + this.name] = labelPoint;
construction.lines.push(line);
if (typeof labelPoint.label.content != 'undefined') {
this.updateSceneData(null, construction, null);
}
}
GeoLine.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" type="text" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Arrow at start: </span>' + '<span class="geoProperty"><input id="firstArrow-' + idNum + '" type="checkbox"' + (this.firstArrow ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Arrow at end: </span>' + '<span class="geoProperty"><input id="lastArrow-' + idNum + '" type="checkbox"' + (this.lastArrow ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">First point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" type="text" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" type="text" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Stroke width: </span>' + '<span class="geoProperty"><input id="strokeWidth-' + idNum + '" type="text" size="5" value="' + this.strokeWidth + '"/></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="labelOffset-' + idNum + '" type="hidden" value="' + JSON.stringify(this.labelOffset) + '"/>');
place.append('<span class="geoItemCaption">Line type: </span><select id="' + 'lineSelect-' + idNum + '"></select><br/>');
var lineSelect = place.find('select#lineSelect-' + idNum);
lineSelect.append('<option value="line"' + (this.lineType == 'line' ? ' selected="selected" ': '') + '>Line</option>');
lineSelect.append('<option value="lineSegment"' + (this.lineType == 'lineSegment' ? ' selected="selected" ': '') + '>Line segment</option>');
lineSelect.append('<option value="endingLine"' + (this.lineType == 'endingLine' ? ' selected="selected" ': '') + '>Starting line segment</option>');
lineSelect.append('<option value="startingLine"' + (this.lineType == 'startingLine' ? ' selected="selected" ': '') + '>Ending line segment</option>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoLine.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var firstArrow = content.find('input#firstArrow-' + idNum).is(':checked');
var lastArrow = content.find('input#lastArrow-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var lineType = content.find('select#lineSelect-' + idNum).val();
var strokeWidth = parseFloat(content.find('input#strokeWidth-' + idNum).val());
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
var labelOffset = JSON.parse(content.find('input#labelOffset-' + idNum).val());
return new GeoLine({'p1' : p1, 'p2' : p2, 'lineType' : lineType, 'name' : name_Str, 'strokeWidth' : strokeWidth, 'showName' : showName, 'visible' : visible, 'firstArrow' : firstArrow, 'lastArrow' : lastArrow, 'dash' : dash, 'color' : color, 'labelOffset' : labelOffset});
}
}
{ // GeoAxis
/**
* Constructor for geometric line object.
*/
var GeoAxis = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'name' : null,
'lineType' : 'line',
'visible' : true,
'color' : '#000',
'majorTickDistance' : 1,
'minorTicks' : 9,
'majorTickHeight' : 20,
'minorTickHeight' : 8,
'drawLabels' : true
}, params);
this.type = 'Axis';
this.p1 = params.p1;
this.p2 = params.p2;
this.name = params.name;
this.lineType = params.lineType;
this.drawLabels = params.drawLabels;
this.visible = params.visible;
this.color = params.color;
this.majorTickDistance = params.majorTickDistance;
this.minorTicks = params.minorTicks;
this.majorTickHeight = params.majorTickHeight;
this.minorTickHeight = params.minorTickHeight;
}
/**
* CSS style defining the icon representing this type.
**/
GeoAxis.prototype.iconCSS = 'axisBtn';
GeoAxis.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoLine to JessieScript.
*/
GeoAxis.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoAxis.prototype.asConstruct = function(board, construction) {
var axis = board.create(
'axis',
[this.p1, this.p2],
{
// Options here.
visible : this.visible,
name : this.name,
straightFirst : ((this.lineType == 'line') || (this.lineType == 'startingLine')),
straightLast : ((this.lineType == 'line') || (this.lineType == 'endingLine')),
color : this.color
}
);
axis.removeAllTicks();
var ticks = board.create(
'ticks',
[axis, this.majorTickDistance],
{
drawLabels : this.drawLabels,
minorTicks : this.minorTicks,
majorTickHeight : this.majorTickHeight,
minorTickHeight : this.minorTickHeight,
}
);
if (construction.axes === undefined) construction.axes = new Array();
construction.axes.push(axis);
}
GeoAxis.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" type="text" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Draw tick labels: </span>' + '<span class="geoProperty"><input id="drawLabels-' + idNum + '" type="checkbox"' + (this.drawLabels? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">First point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" type="text" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" type="text" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Major tick distance: </span>' + '<span class="geoProperty"><input id="matd-' + idNum + '" type="text" size="5" value="' + this.majorTickDistance + '" /></span><br/>');
place.append('<span class="geoItemCaption">Major tick height: </span>' + '<span class="geoProperty"><input id="math-' + idNum + '" type="text" size="5" value="' + this.majorTickHeight + '" /></span><br/>');
place.append('<span class="geoItemCaption">Minor ticks: </span>' + '<span class="geoProperty"><input id="mit-' + idNum + '" type="text" size="5" value="' + this.minorTicks + '" /></span><br/>');
place.append('<span class="geoItemCaption">Minor tick height: </span>' + '<span class="geoProperty"><input id="mith-' + idNum + '" type="text" size="5" value="' + this.minorTickHeight + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<span class="geoItemCaption">Line type: </span><select id="' + 'lineSelect-' + idNum + '"></select><br/>');
var lineSelect = place.find('select#lineSelect-' + idNum);
lineSelect.append('<option value="line"' + (this.lineType == 'line' ? ' selected="selected" ': '') + '>Line</option>');
lineSelect.append('<option value="lineSegment"' + (this.lineType == 'lineSegment' ? ' selected="selected" ': '') + '>Line segment</option>');
lineSelect.append('<option value="endingLine"' + (this.lineType == 'endingLine' ? ' selected="selected" ': '') + '>Starting line segment</option>');
lineSelect.append('<option value="startingLine"' + (this.lineType == 'startingLine' ? ' selected="selected" ': '') + '>Ending line segment</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoAxis.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var drawLabels = content.find('input#drawLabels-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var matd = parseFloat(content.find('input#matd-' + idNum).val());
var math = parseInt(content.find('input#math-' + idNum).val());
var mit = parseInt(content.find('input#mit-' + idNum).val());
var mith = parseInt(content.find('input#mith-' + idNum).val());
var lineType = content.find('select#lineSelect-' + idNum).val();
var color = content.find('input#color-' + idNum).val();
return new GeoAxis({'p1' : p1, 'p2' : p2, 'lineType' : lineType, 'name' : name_Str, 'visible' : visible, 'drawLabels' : drawLabels, 'color' : color, 'majorTickDistance' : matd, 'majorTickHeight' : math, 'minorTicks' : mit, 'minorTickHeight' : mith});
}
}
{ // GeoIntersection
/**
* Constructor for geometric intersection object.
*/
var GeoIntersection = function(params) {
params = $.extend( {
'o1' : null,
'o2' : null,
'name' : null,
'showName' : true,
'visible' : true,
'color' : '#000',
'showPoints' : 'both'
}, params);
this.type = 'Intersection';
this.o1 = params.o1;
this.o2 = params.o2;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
this.showPoints = params.showPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoIntersection.prototype.iconCSS = 'intersectionBtn';
GeoIntersection.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoLine to JessieScript.
*/
GeoIntersection.prototype.asJessieScript = function() { /* Not used. */ return ""; }
GeoIntersection.prototype.asConstruct = function(board, construction) {
var doubleIntersection = (
(board.getElement(this.o1).elType == 'circle') ||
(board.getElement(this.o2).elType == 'circle')
)
construction.points.push(
board.create(
'intersection',
[this.o1, this.o2, 0],
{
visible : this.visible && ((this.showPoints === 'both') || (this.showPoints === 'first')),
name : this.name + "_1",
withLabel : this.showName,
strokeColor: this.color,
fillColor: this.color
}
)
);
construction.points.push(
board.create(
'intersection',
[this.o1, this.o2, 1],
{
visible : this.visible && doubleIntersection && ((this.showPoints === 'both') || (this.showPoints === 'second')),
name : this.name + "_2",
withLabel : this.showName,
strokeColor: this.color,
fillColor: this.color
}
)
);
}
GeoIntersection.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">First line/circle label: </span>' + '<span class="geoProperty"><input id="firstObj-' + idNum + '" size="5" value="' + this.o1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second line/circle label: </span>' + '<span class="geoProperty"><input id="secondObj-' + idNum + '" size="5" value="' + this.o2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<span class="geoItemCaption">Show points: </span><select id="' + 'showSelect-' + idNum + '"></select><br/>');
var showSelect = place.find('select#showSelect-' + idNum);
showSelect.append('<option value="both"' + (this.showPoints == 'both' ? ' selected="selected" ': '') + '>Both intersections</option>');
showSelect.append('<option value="first"' + (this.showPoints == 'first' ? ' selected="selected" ': '') + '>First intersection</option>');
showSelect.append('<option value="second"' + (this.showPoints == 'second' ? ' selected="selected" ': '') + '>Second intersection</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoIntersection.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var o1 = content.find('input#firstObj-' + idNum).val();
var o2 = content.find('input#secondObj-' + idNum).val();
var color = content.find('input#color-' + idNum).val();
var showPoints = content.find('select#showSelect-' + idNum).val();
return new GeoIntersection({'o1' : o1, 'o2' : o2, 'name' : name_Str, 'showPoints' : showPoints, 'showName' : showName, 'visible' : visible, 'color' : color});
}
}
{ // GeoPolygon // TODO incomplete.
/**
* Constructor for regular polygon object.
*/
var GeoPolygon = function(params) {
params = $.extend( {
'pArr' : null,
'name' : null,
'dash' : 0,
'showName' : true,
'visible' : true,
'strokeColor' : '#00f',
'fillColor' : '#0000FF50'
}, params);
this.type = 'Polygon';
this.pArr = params.pArr;
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
}
GeoPolygon.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoPolygon to JessieScript.
*/
GeoPolygon.prototype.asJessieScript = function() { return ""; }
GeoPolygon.prototype.asConstruct = function(board, construction) {
for (var i = 0; i < this.pArr.length; ++i) {
construction.lines.push(
board.create(
'line',
[this.pArr[i], this.pArr[(i + 1) % this.pArr.length]],
{
// Options here.
visible : this.visible,
name : this.name,
withLabel : false,
dash : this.dash
}
)
);
board.create(
'polygon',
this.pArr,
{
// Options here.
visible : this.visible,
name : this.name,
withLabel : false,
dash : this.dash
}
)
}
}
GeoPolygon.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Points: </span>' + '<textarea id="points-' + idNum + '" rows="5" cols="50">' + this.pArr + '</textarea><br/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '" onchange="updateScene(' + boxnum + ', ' + editable + ');"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select, textarea').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoPolygon.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var pArr = content.find('input#points-' + idNum).val().split(',');
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoPolygon({'pArr' : pArr, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'strokeColor' : strokeColor, 'fillColor' : fillColor});
}
}
{ // GeoRegularPolygon
/**
* Constructor for regular polygon object.
*/
var GeoRegularPolygon = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'n' : 6,
'name' : null,
'dash' : 0,
'showName' : true,
'filled' : true,
'strokeColor' : '#00f',
'fillColor' : '#0000FF50',
'pArr' : null,
'visible' : true,
'showGeneratedPoints' : true
}, params);
this.type = 'RegularPolygon';
this.p1 = params.p1;
this.p2 = params.p2;
this.n = parseInt(params.n);
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.filled = params.filled;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.showGeneratedPoints = params.showGeneratedPoints;
this.pArr = (params.pArr == 'null' ? null : params.pArr);
// Check validity.
if (this.n < 3) this.n = 3;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRegularPolygon.prototype.iconCSS = 'regularpolygonBtn';
GeoRegularPolygon.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoRegularPolygon to JessieScript.
*/
GeoRegularPolygon.prototype.asJessieScript = function() { return ""; }
GeoRegularPolygon.prototype.asConstruct = function(board, construction) {
var poly1 = board.create(
'regularpolygon',
[this.p1, this.p2, this.n],
{
// Options here.
visible : this.filled,
strokeColor : this.strokeColor,
borders : {
strokeWidth : 2,
highlightStrokeWidth : 2,
dash : this.dash
},
vertices: {
strokeColor : '#000',
fillColor : '#000',
layer: 6,
visible: this.showGeneratedPoints
},
fillColor : this.fillColor,
highlightFillColor : this.fillColor,
withLines : true,
orthoSensitivity : 0.5,
name : this.name,
withLabel : this.showName
}
);
this.pArr = new Array();
for (var i = 0; i < poly1.vertices.length; ++i) {
construction.points.push(poly1.vertices[i]);
this.pArr[i] = poly1.vertices[i].name;
}
}
GeoRegularPolygon.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Filled: </span>' + '<span class="geoProperty"><input id="filled-' + idNum + '" type="checkbox"' + (this.filled ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Second point label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">N: </span>' + '<span class="geoProperty"><input id="n-' + idNum + '" size="5" value="' + this.n + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<input id="pArr-' + idNum + '" type="hidden" value="' + this.pArr + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoRegularPolygon.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var filled = content.find('input#filled-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var n = content.find('input#n-' + idNum).val();
var pArr = (content.find('input#pArr-' + idNum).val()).split(',');
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
return new GeoRegularPolygon({'p1' : p1, 'p2' : p2, 'n' : n, 'name' : name_Str, 'showName' : showName, 'filled' : filled, 'dash' : dash, 'pArr' : pArr, 'strokeColor' : strokeColor, 'fillColor' : fillColor, 'showGeneratedPoints' : showGeneratedPoints });
}
}
{ // GeoAssociatedLine
/**
* Constructor for geometric line object.
*/
var GeoAssociatedLine = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'name' : null,
'dash' : 0,
'showName' : true,
'visible' : true,
'associationType' : 'normal',
'p2Type' : null,
'color' : '#00f'
}, params);
this.type = 'AssociatedLine';
this.p1 = params.p1;
this.p2 = params.p2;
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.associationType = params.associationType;
this.p2Type = params.p2Type;
this.color = params.color;
}
/**
* CSS style defining the icon representing this type.
**/
GeoAssociatedLine.prototype.iconCSS = 'associatedlineBtn';
GeoAssociatedLine.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoLine to JessieScript.
*/
GeoAssociatedLine.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoAssociatedLine.prototype.asConstruct = function(board, construction) {
if ((this.p2Type == 'Line') || (this.associationType == 'normal')) {
construction.lines.push(
board.create(
this.associationType,
[this.p1, this.p2],
{
visible : this.visible,
name : this.name,
withLabel : this.showName,
dash : this.dash,
color: this.color
}
)
);
}
else if (this.p2Type == 'Circle')
construction.lines.push(
board.create(
'tangent',
[this.p1, this.p2],
{
visible : this.visible,
name : this.name,
withLabel : this.showName,
dash : this.dash,
color : this.color
}
)
);
}
GeoAssociatedLine.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Associated point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Associated line / circle label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="p2Type-' + idNum + '" type="hidden" value="' + this.p2Type + '"/>');
place.append('<span class="geoItemCaption">Association type: </span><select id="associationSelect-' + idNum + '"></select><br/>');
var associationSelect = place.find('select#associationSelect-' + idNum);
associationSelect.append('<option value="normal"' + (this.associationType == 'normal' ? ' selected="selected" ': '') + '>Normal</option>');
associationSelect.append('<option value="parallel"' + (this.associationType == 'parallel' ? ' selected="selected" ': '') + '>Parallel</option>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoAssociatedLine.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var associationType = content.find('select#associationSelect-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var p2Type = content.find('input#p2Type-' + idNum).val();
var color = content.find('input#color-' + idNum).val();
return new GeoAssociatedLine({'p1' : p1, 'p2' : p2, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'associationType' : associationType, 'p2Type' : p2Type, 'color' : color});
}
}
{ // GeoCircle
/**
* Constructor for geometric circle object.
*/
var GeoCircle = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'name' : null,
'dash' : 0,
'showName' : true,
'visible' : true,
'strokeColor' : '#00f',
'fillColor' : 'none'
}, params);
this.type = 'Circle';
this.p1 = params.p1;
this.p2 = params.p2;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.dash = params.dash;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
// Fallback for the older versions.
if (typeof params.color != 'undefined') this.strokeColor = params.color;
}
GeoCircle.prototype.nameStr = function(construction) {
if (this.showName) {
var result = this.name;
for (var property in this) {
result = result.replace(new RegExp('%' + property + '%', 'g'), this[property]);
}
return result;
} else return '';
}
/**
* CSS style defining the icon representing this type.
**/
GeoCircle.prototype.iconCSS = 'circleBtn';
GeoCircle.prototype.updateSceneData = function(index, construction, content) {
var point1 = findPointByName(this.p1, construction);
if (isNaN(this.p2)) {
var point2 = findPointByName(this.p2, construction);
this.radius = Math.round(Math.sqrt( Math.pow(point1.X() - point2.X(), 2) + Math.pow(point1.Y() - point2.Y(), 2) ) * 100) / 100;
} else this.radius = parseFloat(this.p2);
this.area = Math.round(Math.PI * Math.pow(this.radius, 2)* 100) / 100;
this.circumference = Math.round(2 * Math.PI * this.radius * 100) / 100;
var c = findTypeByName('circles', this.name, construction);
if (this.showName) c.label.content.setText(this.nameStr(construction));
}
/**
* Convert a GeoCircle to JessieScript.
*/
GeoCircle.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoCircle.prototype.asConstruct = function(board, construction) {
var c1 = board.create(
'circle',
[this.p1, this.p2],
{
visible : this.visible,
withLabel : this.showName,
name : this.name,
dash : this.dash,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor : this.fillColor
}
);
construction.circles.push(c1);
construction[this.name] = c1;
this.updateSceneData(null, construction, null);
}
GeoCircle.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Center point label: </span>'+ '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Circle point label or radius: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Line style: </span><span class="geoProperty"><select id="' + 'dashSelect-' + idNum + '"></select></span>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoCircle.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoCircle({'p1' : p1, 'p2' : p2, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'strokeColor' : strokeColor, 'fillColor' : fillColor});
}
}
{ // GeoParametricCurve
/**
* Constructor for geometric circle object.
*/
var GeoParametricCurve = function(params) {
params = $.extend( {
'fx' : 't',
'fy' : 't',
'tMin' : -10,
'tMax' : 10,
'name' : null,
'dash' : 0,
'showName' : true,
'visible' : true,
'strokeColor' : '#00f',
'fillColor' : 'none'
}, params);
this.type = 'ParametricCurve';
this.fx = params.fx;
this.fy = params.fy;
this.tMin = params.tMin;
this.tMax = params.tMax;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.dash = params.dash;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
}
/**
* CSS style defining the icon representing this type.
**/
GeoParametricCurve.prototype.iconCSS = 'parametriccurveBtn';
GeoParametricCurve.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoParametricCurve to JessieScript.
*/
GeoParametricCurve.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoParametricCurve.prototype.asConstruct = function(board, construction) {
eval('function x(t) {return ' + $().calculator('parse', this.fx) + '};');
eval('function y(t) {return ' + $().calculator('parse', this.fy) + '};');
construction.functions.push(board.create(
'curve',
[
x,
y,
this.tMin,
this.tMax
],
{
visible : this.visible,
withLabel : this.showName,
name : this.name,
dash : this.dash,
strokeWidth : 2,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor : this.fillColor
}
));
}
GeoParametricCurve.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Function x(t): </span>'+ '<span class="geoProperty"><div id="fx"></div></span><br/>');//'<input id="fx-' + idNum + '" size="30" value="' + this.fx + '"/></span><br/>');
place.append('<span class="geoItemCaption">Function y(t): </span>'+ '<span class="geoProperty"><div id="fy"></div></span><br/>');//'<input id="fy-' + idNum + '" size="30" value="' + this.fy + '"/></span><br/>');
place.find('div#fx').mathquill('editable').mathquill('write', this.fx);
place.find('div#fy').mathquill('editable').mathquill('write', this.fy);
place.append('<span class="geoItemCaption">Range minimum for t: </span>'+ '<span class="geoProperty"><input id="tMin-' + idNum + '" size="5" value="' + this.tMin + '"/></span><br/>');
place.append('<span class="geoItemCaption">Range maximum for t: </span>'+ '<span class="geoProperty"><input id="tMax-' + idNum + '" size="5" value="' + this.tMax + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select, div#fx, div#fy').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoParametricCurve.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var fx = content.find('div#fx').mathquill('latex');//content.find('input#fx-' + idNum).val();
var fy = content.find('div#fy').mathquill('latex');//content.find('input#fy-' + idNum).val();
var tMin = content.find('input#tMin-' + idNum).val();
var tMax = content.find('input#tMax-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoParametricCurve({'fx' : fx, 'fy' : fy, 'tMin' : tMin, 'tMax' : tMax, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'strokeColor' : strokeColor, 'fillColor' : fillColor});
}
}
{ // GeoSquare
/**
* Constructor for geometric square object.
*/
var GeoSquare = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'name' : null,
'dash' : 0,
'showName' : false,
'visible' : true,
'strokeColor' : '#00f',
'fillColor' : 'none',
'p3' : null,
'showGeneratedPoints' : true
}, params);
if (typeof params.color != 'undefined') params.strokeColor = params.color;
this.type = 'Square';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.dash = params.dash;
this.showName = params.showName;
this.visible = params.visible;
this.strokeColor = params.strokeColor;
this.showGeneratedPoints = params.showGeneratedPoints;
this.fillColor = params.fillColor;
var n;
if (params.p3 != null) n = parseInt(params.p3);
else n = popNewGlobalIndex(2);
this.p3 = n;
this.p4 = n + 1;
}
/**
* CSS style defining the icon representing this type.
**/
GeoSquare.prototype.iconCSS = 'squareBtn';
GeoSquare.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoLine to JessieScript.
*/
GeoSquare.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoSquare.prototype.asConstruct = function(board, construction) {
var p1 = findPointByName(this.p1, construction);
var p2 = findPointByName(this.p2, construction);
var lAB = board.create(
'line',
[p1, p2],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
);
var n1 = board.create('normal', [p1, lAB], { visible : false } );
var n2 = board.create('normal', [p2, lAB], { visible : false } );
var c1 = board.create('circle', [p1, p2], { visible : false } );
var c2 = board.create('circle', [p2, p1], { visible : false } );
var i1 = board.create(
'intersection',
[c1, n1, 0],
{
visible : this.visible && this.showGeneratedPoints,
strokeColor : '#000',
fillColor : '#000',
name : 'P' + this.p3
}
);
var i2 = board.create(
'intersection',
[c2, n2, 0],
{
visible:this.visible && this.showGeneratedPoints,
strokeColor : '#000',
fillColor : '#000',
name : 'P' + this.p4
}
);
var lAC = board.create(
'line',
[p1, i1],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
);
var lAD = board.create(
'line',
[p2, i2],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
);
var lCD = board.create(
'line',
[i1, i2],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
);
construction.lines.push(lAB);
construction.lines.push(lAC);
construction.lines.push(lAD);
construction.lines.push(lCD);
construction.intersections.push(i1);
construction.intersections.push(i2);
construction.polygons.push(board.create(
'polygon',
[p1, p2, i2, i1],
{
visible : this.visible,
name : this.name,
withLines : false,
withLabel : this.showName,
dash : this.dash,
strokeColor : 'none',
fillColor : this.fillColor,
fillOpacity : 1.0,
highlightFillOpacity : 1.0,
highlightStrokeColor : 'none',
highlightFillColor : this.fillColor,
}
));
}
GeoSquare.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Second point label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.p3 + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoSquare.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var n = content.find('input#nParam-' + idNum).val();
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoSquare({ 'p1' : p1, 'p2' : p2, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'p3' : n, 'strokeColor' : strokeColor, 'fillColor' : fillColor, 'showGeneratedPoints' : showGeneratedPoints });
}
}
{ // GeoTriangle
/**
* Constructor for geometric triangle object.
*/
var GeoTriangle = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3' : null,
'name' : null,
'dash' : 0,
'showName' : false,
'visible' : true,
'strokeColor' : '#00f',
'fillColor' : 'none'
}, params);
this.type = 'Triangle';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.dash = params.dash;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
// Fallback for the older versions.
if (typeof params.color != 'undefined') this.strokeColor = params.color;
}
/**
* CSS style defining the icon representing this type.
**/
GeoTriangle.prototype.iconCSS = 'triangleBtn';
GeoTriangle.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoTriangle to JessieScript.
*/
GeoTriangle.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoTriangle.prototype.asConstruct = function(board, construction) {
construction.lines.push(
board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
)
);
construction.lines.push(
board.create(
'line',
[this.p2, this.p3],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
)
);
construction.lines.push(
board.create(
'line',
[this.p1, this.p3],
{
visible : this.visible,
name : '',
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
)
);
construction.polygons.push(
board.create(
'polygon',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
name : this.name,
withLabel : this.showName,
withLines : false,
straightFirst : false,
straightLast : false,
fillColor : this.fillColor,
fillOpacity : 1.0,
borders : {
strokeColor : this.strokeColor
}
}
)
);
}
GeoTriangle.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First corner point label: </span>'+ '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Second corner point label: </span>'+ '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Third corner point label: </span>'+ '<span class="geoProperty"><input id="thirdPoint-' + idNum + '" size="5" value="' + this.p3 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoTriangle.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3 = content.find('input#thirdPoint-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoTriangle({ 'p1' : p1, 'p2' : p2, 'p3' : p3, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'strokeColor' : strokeColor, 'fillColor' : fillColor});
}
}
{ // GeoSector
/**
* Constructor for geometric sector object.
*/
var GeoSector = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3' : null,
'l1' : null,
'name' : null,
'dash' : 0,
'showName' : true,
'visible' : true,
'mode' : 'sector',
'strokeColor' : '#00f',
'fillColor' : '#0000FF50',
'fillOpacity': 0.3
}, params);
this.type = 'Sector';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.dash = params.dash;
this.mode = params.mode;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.fillOpacity = params.fillOpacity;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(1);
this.l1 = n;
}
/**
* CSS style defining the icon representing this type.
**/
GeoSector.prototype.iconCSS = 'sectorBtn';
GeoSector.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoSector to JessieScript.
*/
GeoSector.prototype.asJessieScript = function() {
return "";
}
GeoSector.prototype.asConstruct = function(board, construction) {
if (this.mode == 'sector') {
board.create(
'sector',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor : this.fillColor,
fillOpacity : this.fillOpacity,
highlightFillOpacity : this.fillOpacity,
withLines : true,
name : this.name,
withLabel : this.showName,
strokeWidth : 2,
highlightStrokeWidth : 2,
dash : this.dash
}
);
} else if (this.mode == 'arc') {
board.create(
'arc',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
strokeColor : this.strokeColor,
withLines : true,
name : this.name,
withLabel : this.showName,
strokeWidth : 2,
highlightStrokeWidth : 2,
dash : this.dash
}
);
}
else /* if (this.mode == 'segment') */ {
var l1 = board.create('line', [this.p1, this.p3], { visible : false });
var arc1 = board.create(
'arc',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
strokeColor : this.strokeColor,
fillColor : this.fillColor,
highlightFillColor : this.fillColor,
fillOpacity : this.fillOpacity,
highlightFillOpacity : this.fillOpacity,
withLines : true,
name : this.name,
withLabel : this.showName,
strokeWidth : 2,
highlightStrokeWidth : 2,
dash : this.dash
}
);
var i1 = board.create('intersection', [l1, arc1], { visible : false });
construction.lines.push(
board.create(
'line',
[this.p2, i1],
{
visible : this.visible,
strokeColor : this.strokeColor,
withLines : true,
name : 'l' + this.l1,
straightFirst : false,
straightLast : false,
withLabel : false,
strokeWidth : 2,
highlightStrokeWidth : 2,
dash : this.dash
}
)
);
}
}
GeoSector.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Third corner point label: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Radius point label: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Angle point label: </span>' + '<span class="geoProperty"><input id="thirdPoint-' + idNum + '" size="5" value="' + this.p3 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill opacity: </span>' + '<span class="geoProperty"><input id="fill-' + idNum + '" type="text" size="8" value="' + this.fillOpacity + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Mode: </span><select id="' + 'modeSelect-' + idNum + '"></select><br/>');
var modeSelect = place.find('select#modeSelect-' + idNum);
modeSelect.append('<option value="sector"' + (this.mode == 'sector' ? ' selected="selected" ': '') + '>Sector</option>');
modeSelect.append('<option value="arc"' + (this.mode == 'arc' ? ' selected="selected" ': '') + '>Arc</option>');
modeSelect.append('<option value="segment"' + (this.mode == 'segment' ? ' selected="selected" ': '') + '>Segment</option>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoSector.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var visible = content.find('input#visible-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3 = content.find('input#thirdPoint-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var mode = content.find('select#modeSelect-' + idNum).val();
var nParam = content.find('input#nParam-' + idNum).val();
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
var fillOpacity = content.find('input#fillOpacity-' + idNum).val();
return new GeoSector({ 'p1' : p1, 'p2' : p2, 'p3' : p3, 'name' : name_Str, 'mode' : mode, 'showName' : showName, 'visible' : visible, 'dash' : dash, 'l1' : nParam, 'strokeColor' : strokeColor, 'fillColor' : fillColor, 'fillOpacity' : fillOpacity });
}
}
{ // GeoAngle
/**
* Constructor for geometric angle object.
*/
var GeoAngle = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3' : null,
'name' : null,
'showName' : true,
'visible' : true,
'mode' : 'angle',
'strokeColor' : 'red',
'fillColor' : 'red',
'radius' : 1.0,
'fillOpacity': 0.3,
'label' : {
'fixed' : false
}
}, params);
this.type = 'Angle';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.name = params.name;
this.showName = params.showName;
this.fillOpacity = params.fillOpacity;
this.visible = params.visible;
this.mode = params.mode;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
this.radius = params.radius;
}
/**
* CSS style defining the icon representing this type.
**/
GeoAngle.prototype.iconCSS = 'angleBtn';
GeoAngle.prototype.updateSceneData = function(index, construction, content) {
/* Not used. */
}
GeoAngle.prototype.angleVal = function(construction) {
var p1 = findPointByName(this.p1, construction);
var p2 = findPointByName(this.p2, construction);
var p3 = findPointByName(this.p3, construction);
return JXG.Math.Geometry.trueAngle(p1, p2, p3).toFixed(0);
}
GeoAngle.prototype.angleStr = function(construction) {
if (this.showName) {
var angle = this.angleVal(construction) + '°';
if (this.name == '') {
var angleValue = this.angleVal(construction);
if ((angleValue == 90) || ((angleValue == 270) && (this.mode == 'angleSmall'))) return ' ';
else return angle;
} else return this.name.replace(/%1/g, angle);
} else return '';
}
/**
* Convert a GeoAngle to JessieScript.
*/
GeoAngle.prototype.asJessieScript = function() {
return "";//this.name + " = <(" + this.p1 + ", " + this.p2 + ", " + this.p3 + ")" + (this.visible ? (this.showName ? "" : " nolabel") : " invisible") + ";\n";
}
GeoAngle.prototype.asConstruct = function(board, construction) {
var obj = this;
if ((this.mode == 'angle') || (this.mode == 'angleSmall') || (this.mode == 'angleLarge')) {
construction.angles.push(
board.create(
'angle',
[this.p1, this.p2, this.p3],
{
strokeColor : this.strokeColor,
visible : this.visible && (
(this.mode == 'angle') ||
(
(this.mode == 'angleSmall') &&
this.angleVal(construction) <= 180
) ||
(
(this.mode == 'angleLarge') &&
this.angleVal(construction) >= 180
)
),
strokeWidth : 2,
needsRegularUpdate : true,
fillColor : this.fillColor,
fillOpacity : this.fillOpacity,
highlightFillOpacity : this.fillOpacity,
orthoSensitivity : 0.5,
label : { strokeColor : 'black' },
point : { visible : false },
radius : this.radius,
withLabel : true,
name : function() {
if (this.obj === undefined) this.obj = obj;
if ((this.obj.mode == 'angleSmall') || (this.obj.mode == 'angleLarge')) {
var ang = this.obj.angleVal(construction);
if ((ang > 180) && ((typeof this.oldAngle == 'undefined') || (this.oldAngle <= 180))) {
for (el in this.ancestors)
if (this.ancestors[el].elType == 'angle') {
if (this.obj.mode == 'angleSmall') this.ancestors[el].hideElement();
else if (this.obj.mode == 'angleLarge') this.ancestors[el].showElement();
}
this.oldAngle = ang;
if (typeof this.rendNode != 'undefined') this.update();
} else if ((ang <= 180) && ((typeof this.oldAngle == 'undefined') || (this.oldAngle > 180))) {
for (el in this.ancestors)
if (this.ancestors[el].elType == 'angle') {
if (this.obj.mode == 'angleSmall') this.ancestors[el].showElement();
else if (this.obj.mode == 'angleLarge') this.ancestors[el].hideElement();
}
this.oldAngle = ang;
if (typeof this.rendNode != 'undefined') this.update();
}
}
return this.obj.angleStr(construction);
}
}
)
);
if ((this.mode == 'angleSmall') || (this.mode == 'angleLarge'))
construction.angles.push(
board.create(
'angle',
[this.p3, this.p2, this.p1],
{
strokeColor : this.strokeColor,
visible : !(this.visible && (
(this.mode == 'angle') ||
(
(this.mode == 'angleSmall') &&
this.angleVal(construction) <= 180
) ||
(
(this.mode == 'angleLarge') &&
this.angleVal(construction) >= 180
)
)),
strokeWidth : 2,
needsRegularUpdate : true,
fillColor : this.fillColor,
fillOpacity : this.fillOpacity,
highlightFillOpacity : this.fillOpacity,
orthoSensitivity : 0.5,
label : { strokeColor : 'black' },
point : { visible : false },
radius : this.radius,
withLabel : true,
name : function() {
if (this.obj === undefined) this.obj = obj;
if ((this.obj.mode == 'angleSmall') || (this.obj.mode == 'angleLarge')) {
var ang = this.obj.angleVal(construction);
if ((ang <= 180) && ((typeof this.oldAngle == 'undefined') || (this.oldAngle > 180))) {
for (el in this.ancestors)
if (this.ancestors[el].elType == 'angle') {
if (this.obj.mode == 'angleSmall') this.ancestors[el].hideElement();
else if (this.obj.mode == 'angleLarge') this.ancestors[el].showElement();
}
this.hideElement();
this.oldAngle = ang;
if (typeof this.rendNode != 'undefined') this.update();
} else if ((ang > 180) && ((typeof this.oldAngle == 'undefined') || (this.oldAngle <= 180))) {
for (el in this.ancestors)
if (this.ancestors[el].elType == 'angle') {
if (this.obj.mode == 'angleSmall') this.ancestors[el].showElement();
else if (this.obj.mode == 'angleLarge') this.ancestors[el].hideElement();
}
this.showElement();
this.oldAngle = ang;
if (typeof this.rendNode != 'undefined') this.update();
}
}
return this.obj.angleStr(construction);
}
}
)
);
}
if (this.mode == 'bisector') {
construction.lines.push(
board.create(
'bisector',
[this.p1, this.p2, this.p3],
{
visible : this.visible,
strokeWidth : 2,
needsRegularUpdate : true,
name : this.name,
withLabel : this.showName,
color : this.strokeColor
}
)
);
}
}
GeoAngle.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Point on the right hand side: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Corner point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Point on the left hand side: </span>' + '<span class="geoProperty"><input id="thirdPoint-' + idNum + '" size="5" value="' + this.p3 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Radius: </span>' + '<span class="geoProperty"><input id="radius-' + idNum + '" type="text" size="5" value="' + this.radius + '" /></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill opacity: </span>' + '<span class="geoProperty"><input id="fillOpacity-' + idNum + '" type="text" size="8" value="' + this.fillOpacity + '" /></span><br/>');
place.append('<span class="geoItemCaption">Mode: </span><select id="' + 'modeSelect-' + idNum + '"></select><p />');
var modeSelect = place.find('select#modeSelect-' + idNum);
modeSelect.append('<option value="angle"' + (this.mode == 'angle' ? ' selected="selected" ': '') + '>Angle</option>');
modeSelect.append('<option value="angleSmall"' + (this.mode == 'angleSmall' ? ' selected="selected" ': '') + '>Small angle</option>');
modeSelect.append('<option value="angleLarge"' + (this.mode == 'angleLarge' ? ' selected="selected" ': '') + '>Large angle</option>');
modeSelect.append('<option value="bisector"' + (this.mode == 'bisector' ? ' selected="selected" ': '') + '>Bisector</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoAngle.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3 = content.find('input#thirdPoint-' + idNum).val();
var radius = parseFloat(content.find('input#radius-' + idNum).val());
var mode = content.find('select#modeSelect-' + idNum).val();
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
var fillOpacity = content.find('input#fillOpacity-' + idNum).val();
return new GeoAngle({ 'p1' : p1, 'p2' : p2, 'p3' : p3, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'mode' : mode, 'strokeColor' : strokeColor, 'fillColor' : fillColor, 'fillOpacity' : fillOpacity, 'radius' : radius });
}
}
{ // GeoParallelogram
/**
* Constructor for geometric parallelogram object.
*/
var GeoParallelogram = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3' : null,
'l1' : null,
'name' : null,
'dash' : 0,
'showName' : false,
'visible' : true,
'strokeColor' : 'blue',
'fillColor' : 'none',
'showGeneratedPoints' : true
}, params);
// Fallback for the older versions.
if (typeof params.color != 'undefined') params.strokeColor = params.color;
this.type = 'Parallelogram';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.dash = params.dash;
this.strokeColor = params.strokeColor;
this.fillColor = params.fillColor;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(5);
this.l1 = n;
this.l2 = n + 1;
this.l3 = n + 2;
this.l4 = n + 3;
this.p4 = n + 4;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.showGeneratedPoints = params.showGeneratedPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoParallelogram.prototype.iconCSS = 'parallelogramBtn';
GeoParallelogram.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Convert a GeoParallelogram to JessieScript.
*/
GeoParallelogram.prototype.asJessieScript = function() { return ''; /* Not used. */ }
GeoParallelogram.prototype.asConstruct = function(board, construction) {
var p1 = findPointByName(this.p1, construction);
var p2 = findPointByName(this.p2, construction);
var p3 = findPointByName(this.p3, construction);
var l1 = board.create(
'line',
[p1, p2],
{
visible : this.visible,
name : 'l' + this.l1,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
var l2 = board.create(
'line',
[p2, p3],
{
visible : this.visible,
name : 'l' + this.l2,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
);
var l3 = board.create('parallel', [p1, l2], { name : 'l' + this.l3, visible : false } );
var l4 = board.create('parallel', [p3, l1], { name : 'l' + this.l4, visible : false } );
var p4 = board.create(
'intersection',
[l3, l4, 0],
{
visible : this.visible && this.showGeneratedPoints,
strokeColor : '#000',
fillColor : '#000',
name : 'P' + this.p4
}
);
construction.points.push(p1);
construction.points.push(p2);
construction.points.push(p3);
construction.points.push(p4);
construction.lines.push(board.create(
'line',
[p1, p4],
{
visible : this.visible,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
));
construction.lines.push(board.create(
'line',
[p3, p4],
{
visible : this.visible,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.strokeColor
}
));
constr = construction;
construction.lines.push(l1);
construction.lines.push(l2);
construction.polygons.push(board.create(
'polygon',
[p1, p2, p3, p4],
{
visible : this.visible,
name : this.name,
withLines : false,
withLabel : this.showName,
dash : this.dash,
strokeColor : 'none',
fillColor : this.fillColor,
fillOpacity : 1.0,
highlightFillOpacity : 1.0,
highlightStrokeColor : 'none',
highlightFillColor : this.fillColor,
}
));
}
GeoParallelogram.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show generated point: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Second point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Third point: </span>' + '<span class="geoProperty"><input id="thirdPoint-' + idNum + '" size="5" value="' + this.p3 + '"/></span><br/>');
place.append('<span class="geoItemCaption">Stroke color: </span>' + '<span class="geoProperty"><input id="strokeColor-' + idNum + '" type="text" size="8" value="' + this.strokeColor + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fill color: </span>' + '<span class="geoProperty"><input id="fillColor-' + idNum + '" type="text" size="8" value="' + this.fillColor + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoParallelogram.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3 = content.find('input#thirdPoint-' + idNum).val();
var nParam = content.find('input#nParam-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var strokeColor = content.find('input#strokeColor-' + idNum).val();
var fillColor = content.find('input#fillColor-' + idNum).val();
return new GeoParallelogram({ 'p1' : p1, 'p2' : p2, 'p3' : p3, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'l1' : nParam, 'dash' : dash, 'fillColor' : fillColor, 'strokeColor' : strokeColor, 'showGeneratedPoints' : showGeneratedPoints});
}
}
{ // GeoLabel
/**
* Constructor for geometric label object.
*/
var GeoLabel = function(params) {
params = $.extend( {
'x' : null,
'y' : null,
'name' : null,
'value' : 'Label caption',
'visible' : true,
'color' : '#000',
'fixed' : true
}, params);
this.type = 'Label';
this.x = params.x;
this.y = params.y;
this.name = params.name;
this.value = params.value;
this.visible = params.visible;
this.color = params.color;
this.fixed = params.fixed;
}
/**
* CSS style defining the icon representing this type.
**/
GeoLabel.prototype.iconCSS = 'labelBtn';
GeoLabel.prototype.updateSceneData = function(index, construction, content) {
// Update values to scene array.
var j = -1;
do ++j; while (this.name != construction.texts[j].name);
// Two decimal precision.
var newX = parseInt(construction.texts[j].coords.usrCoords[1] * 100) / 100;
var newY = parseInt(construction.texts[j].coords.usrCoords[2] * 100) / 100;
this.x = newX;
this.y = newY;
// Update values to construct accordion.
content.find('input#xCoordinate-' + index).val(newX);
content.find('input#yCoordinate-' + index).val(newY);
}
/**
* Convert a GeoLabel to JessieScript.
*/
GeoLabel.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoLabel.prototype.asConstruct = function(board, construction) {
construction.texts.push(
board.create(
'text',
[this.x, this.y, this.value],
{
name : this.name,
visible : this.visible,
color : this.color,
fixed : this.fixed
}
)
);
}
GeoLabel.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="15" value="' + this.name + '"/></span><br/>');
place.append('<span class="geoItemCaption">Caption: </span>' + '<span class="geoProperty"><input id="value-' + idNum + '" size="15" value="' + this.value + '"/></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Fixed: </span>' + '<span class="geoProperty"><input id="fixed-' + idNum + '" type="checkbox"' + (this.fixed ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">x-coordinate: </span>' + '<span class="geoProperty"><input id="xCoordinate-' + idNum + '" size="5" value="' + this.x + '"/></span><br/>');
place.append('<span class="geoItemCaption">y-coordinate: </span>' + '<span class="geoProperty"><input id="yCoordinate-' + idNum + '" size="5" value="' + this.y + '"/></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoLabel.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var valueStr = content.find('input#value-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var fixed = content.find('input#fixed-' + idNum).is(':checked');
var x = parseFloat(content.find('input#xCoordinate-' + idNum).val());
var y = parseFloat(content.find('input#yCoordinate-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
return new GeoLabel({ 'x' : x, 'y' : y, 'name' : name_Str, 'value' : valueStr, 'visible' : visible, 'color' : color, 'fixed' : fixed });
}
}
{ // GeoRhombus // TODO to JXG.
/**
* Constructor for geometric rhombus object.
*/
var GeoRhombus = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3x' : null,
'p3y' : null,
'l1' : null,
'dash' : 0,
'name' : null,
'showName' : true,
'visible' : true,
'color' : '#00f',
'showGeneratedPoints' : true
}, params);
this.type = 'Rhombus';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3x = (params.p3x == 'null' ? null : params.p3x);
this.p3y = (params.p3y == 'null' ? null : params.p3y);
this.dash = params.dash;
this.color = params.color;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(7);
this.l1 = n;
this.l2 = n + 1;
this.l3 = n + 2;
this.l4 = n + 3;
this.p3 = n + 4;
this.p4 = n + 5;
this.c1 = n + 6;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.showGeneratedPoints = params.showGeneratedPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRhombus.prototype.iconCSS = 'rhombusBtn';
GeoRhombus.prototype.updateSceneData = function(index, construction, content) {
// Update values to scene array.
var p3 = findPointByName('P' + this.p3, construction);
// Two decimal precision.
var newX = parseInt(p3.coords.usrCoords[1] * 100) / 100;
var newY = parseInt(p3.coords.usrCoords[2] * 100) / 100;
this.p3x = newX;
this.p3y = newY;
// Update values to construct accordion.
content.find('input#thirdPointX-' + index).val(newX);
content.find('input#thirdPointY-' + index).val(newY);
}
/**
* Convert a GeoRhombus to JessieScript.
*/
GeoRhombus.prototype.asJessieScript = function() {
var s = "c" + this.c1 + " = k(" + this.p1 + ", " + this.p2 + ") invisible;\n";
s += "P" + this.p3 + "(" + "c" + this.c1 + ((this.p3x != null) && (this.p3y != null) ? ', ' + this.p3x + ', ' + this.p3y : "") + ")" + (this.showGeneratedPoints ? '' : ' invisible') + ";\n";
s += "l" + this.l1 + " = [" + this.p1 + " " + this.p2 + "] nolabel;\n";
s += "l" + this.l2 + " = [" + this.p1 + " P" + this.p3 + "] nolabel;\n";
s += "l" + this.l3 + " = ||(" + this.p2 + ", l" + this.l2 + ") invisible;\n";
s += "l" + this.l4 + " = ||(P" + this.p3 + ", l" + this.l1 + ") invisible;\n";
s += "P" + this.p4 + " = l" + this.l3 + "&l" + this.l4 + (this.showGeneratedPoints ? '' : ' invisible') + ";\n";
s += "[P" + this.p3 + " P" + this.p4 + "];\n";
s += "[" + this.p2 + " P" + this.p4 + "];\n";
return s;
}
GeoRhombus.prototype.asConstruct = function(board, construction) { /* Not used. */ }
GeoRhombus.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point x: </span>' + '<span class="geoProperty"><input id="thirdPointX-' + idNum + '" size="5" value="' + this.p3x + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point y: </span>' + '<span class="geoProperty"><input id="thirdPointY-' + idNum + '" size="5" value="' + this.p3y + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoRhombus.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3x = content.find('input#thirdPointX-' + idNum).val();
var p3y = content.find('input#thirdPointY-' + idNum).val();
var nParam = content.find('input#nParam-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
return new GeoRhombus( {'p1' : p1, 'p2' : p2, 'p3x' : p3x, 'p3y' : p3y, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'l1' : nParam, 'dash' : dash, 'color' : color, 'showGeneratedPoints' : showGeneratedPoints});
}
}
{ // GeoRestrictedTriangle
/**
* Constructor for restricted triangle object.
*/
var GeoRestrictedTriangle = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3x' : null,
'p3y' : null,
'l1' : null,
'name' : null,
'showName' : true,
'visible' : true,
'color' : '#00f',
'dash' : 0,
'restriction' : 'rightangle',
'showGeneratedPoints' : true
}, params);
this.type = 'RestrictedTriangle';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3x = (params.p3x == 'null' ? null : params.p3x);
this.p3y = (params.p3y == 'null' ? null : params.p3y);
this.color = params.color;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(4);
this.l1 = n;
this.l2 = n + 1;
this.l3 = n + 2;
this.p3 = n + 3;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.dash = params.dash;
this.restriction = params.restriction;
this.showGeneratedPoints = params.showGeneratedPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRestrictedTriangle.prototype.iconCSS = 'restrictedtriangleBtn';
GeoRestrictedTriangle.prototype.updateSceneData = function(index, construction, content) {
// Update values to scene array.
var p3 = findPointByName('P' + this.p3, construction);
// Two decimal precision.
var newX = parseInt(p3.coords.usrCoords[1] * 100) / 100;
var newY = parseInt(p3.coords.usrCoords[2] * 100) / 100;
this.p3x = newX;
this.p3y = newY;
// Update values to construct accordion.
content.find('input#thirdPointX-' + index).val(newX);
content.find('input#thirdPointY-' + index).val(newY);
}
/**
* Convert a GeoRestrictedTriangle to JessieScript.
*/
GeoRestrictedTriangle.prototype.asJessieScript = function() { return ""; }
GeoRestrictedTriangle.prototype.asConstruct = function(board, construction) {
// Construct the assisting circle(s).
var c1, c2;
if (this.restriction == 'rightangle') {
var mp1 = board.create('midpoint', [this.p1, this.p2], { visible : false });
c1 = board.create('circle', [mp1, this.p1], { visible : false } );
} else /* if ((this.restriction == 'isosceles'), (this.restriction == 'equilateral')) */ {
c1 = board.create('circle', [this.p2, this.p1], { visible : false } );
if (this.restriction == 'equilateral')
c2 = board.create('circle', [this.p1, this.p2], { visible : false } );
}
// Construct the third (restricted) point of the triangle.
var g1;
if (this.restriction == 'equilateral') {
g1 = board.create('intersection', [c1, c2, 0], { visible : this.visible && this.showGeneratedPoints, name : "P" + this.p3, strokeColor : '#000',
fillColor : '#000', withLabel : this.showName } );
} else /* if ((this.restriction == 'rightangle') || (this.restriction == 'isosceles')) */ {
if ((this.p3x != null) && (this.p3y != null))
g1 = board.create('glider', [this.p3x, this.p3y, c1], { visible : this.visible && this.showGeneratedPoints, name : "P" + this.p3, withLabel : this.showName } );
else
g1 = board.create('glider', [c1], { visible : this.visible && this.showGeneratedPoints, name : "P" + this.p3, withLabel : this.showName } );
}
construction.points.push(g1);
construction.lines.push(
board.create(
'line',
[this.p1, this.p2],
{
visible : this.visible,
name : 'l' + this.l1,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
)
);
construction.lines.push(
board.create(
'line',
[this.p1, g1],
{
visible : this.visible,
name : 'l' + this.l2,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
)
);
construction.lines.push(
board.create(
'line',
[g1, this.p2],
{
visible : this.visible,
name : 'l' + this.l3,
withLabel : false,
straightFirst : false,
straightLast : false,
dash : this.dash,
color : this.color
}
)
);
}
GeoRestrictedTriangle.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point x: </span>' + '<span class="geoProperty"><input id="thirdPointX-' + idNum + '" size="5" value="' + this.p3x + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point y: </span>' + '<span class="geoProperty"><input id="thirdPointY-' + idNum + '" size="5" value="' + this.p3y + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Type of restriction: </span><select id="' + 'restrictionSelect-' + idNum + '" ></select><br/>');
var restrictionSelect = place.find('select#restrictionSelect-' + idNum);
restrictionSelect.append('<option value="rightangle"' + (this.restriction == 'rightangle' ? ' selected="selected" ': '') + '>Right angle</option>');
restrictionSelect.append('<option value="isosceles"' + (this.restriction == 'isosceles' ? ' selected="selected" ': '') + '>Isosceles</option>');
restrictionSelect.append('<option value="equilateral"' + (this.restriction == 'isosceles' ? ' selected="selected" ': '') + '>Equilateral</option>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoRestrictedTriangle.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3x = content.find('input#thirdPointX-' + idNum).val();
var p3y = content.find('input#thirdPointY-' + idNum).val();
var nParam = content.find('input#nParam-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var restriction = content.find('select#restrictionSelect-' + idNum).val();
var color = content.find('input#color-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
return new GeoRestrictedTriangle( { 'p1' : p1, 'p2' : p2, 'p3x' : p3x, 'p3y' : p3y, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'l1' : nParam, 'dash' : dash, 'restriction' : restriction, 'color' : color, 'showGeneratedPoints' : showGeneratedPoints});
}
}
{ // GeoTrapezoid // TODO to JXG.
/**
* Constructor for geometric trapezoid object.
*/
var GeoTrapezoid = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3' : null,
'p4x' : null,
'p4y' : null,
'l1' : null,
'name' : null,
'showName' : true,
'visible' : true,
'color' : '#f00',
'dash' : 0,
'showGeneratedPoints' : true
}, params);
this.type = 'Trapezoid';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3 = params.p3;
this.p4x = (params.p4x == 'null' ? null : params.p4x);
this.p4y = (params.p4y == 'null' ? null : params.p4y);
this.dash = params.dash;
this.color = params.color;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(8);
this.l1 = n;
this.l2 = n + 1;
this.l3 = n + 2;
this.p4 = n + 3;
this.p5 = n + 4;
this.p6 = n + 5;
this.c1 = n + 6;
this.c2 = n + 7;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.showGeneratedPoints = params.showGeneratedPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoTrapezoid.prototype.iconCSS = 'trapezoidBtn';
GeoTrapezoid.prototype.updateSceneData = function(index, construction, content) {
// Update values to scene array.
var p4 = findPointByName('P' + this.p4, construction);
// Two decimal precision.
var newX = parseInt(p4.coords.usrCoords[1] * 100) / 100;
var newY = parseInt(p4.coords.usrCoords[2] * 100) / 100;
this.p4x = newX;
this.p4y = newY;
// Update values to construct accordion.
content.find('input#fourthPointX-' + index).val(newX);
content.find('input#fourthPointY-' + index).val(newY);
}
/**
* Convert a GeoTrapezoid to JessieScript.
*/
GeoTrapezoid.prototype.asJessieScript = function() {
var s = 'l' + this.l1 + ' = [' + this.p1 + ' ' + this.p2 + "] nolabel;\n";
s += 'l' + this.l2 + ' = ||(l' + this.l1 + ', ' + this.p3 + ") invisible;\n";
s += 'c' + this.c1 + ' = k(' + this.p3 + ", 0.1) invisible;\n";
s += 'c' + this.c2 + ' = k(' + this.p3 + ", 0.2) invisible;\n";
s += 'P' + this.p5 + ' = c' + this.c1 + '&l' + this.l2 + " invisible;\n";
s += 'P' + this.p6 + ' = c' + this.c2 + '&l' + this.l2 + " invisible;\n";
s += 'l' + this.l3 + ' = ]P' + this.p5 + '_1 P' + this.p6 + "_1] invisible;\n";
s += 'P' + this.p4 + '(l' + this.l3 + ((this.p4x != null) && (this.p4y != null) ? ', ' + this.p4x + ', ' + this.p4y : "") + ')' + (this.showGeneratedPoints ? '' : ' invisible') + ";\n";
s += '[' + this.p3 + ' P' + this.p4 + "] nolabel;\n";
s += '[' + this.p1 + ' ' + this.p3 + "] nolabel;\n";
s += '[' + this.p2 + ' P' + this.p4 + "] nolabel;\n";
return s;
}
GeoTrapezoid.prototype.asConstruct = function(board, construction) { /* Not used. */ }
GeoTrapezoid.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">First point: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point: </span>' + '<span class="geoProperty"><input id="thirdPoint-' + idNum + '" size="5" value="' + this.p3 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fourth point x: </span>' + '<span class="geoProperty"><input id="fourthPointX-' + idNum + '" size="5" value="' + this.p4x + '" /></span><br/>');
place.append('<span class="geoItemCaption">Fourth point y: </span>' + '<span class="geoProperty"><input id="fourthPointY-' + idNum + '" size="5" value="' + this.p4y + '" /></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoTrapezoid.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3 = content.find('input#thirdPoint-' + idNum).val();
var p4x = content.find('input#fourthPointX-' + idNum).val();
var p4y = content.find('input#fourthPointY-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
var nParam = content.find('input#nParam-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
return new GeoTrapezoid({'p1' : p1, 'p2' : p2, 'p3' : p3, 'p4x' : p4x, 'p4y' : p4y, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'l1' : nParam, 'dash' : dash, 'color' : color, 'showGeneratedPoints' : showGeneratedPoints});
}
}
{ // GeoScriptable
/**
* Constructor for a scriptable (JessieScript) object.
*/
var GeoScriptable = function(params) {
params = $.extend( {
'name' : null,
'script' : '',
}, params);
this.type = 'Scriptable';
this.name = params.name;
this.script = params.script;
}
GeoScriptable.prototype.updateSceneData = function(index, construction, content) { /* Not used. */ }
/**
* Passthrough function for upper level compatibility
* (GeoScriptable is already JessieScript).
*/
GeoScriptable.prototype.asJessieScript = function() {
return this.script + "\n";
}
GeoScriptable.prototype.asConstruct = function(board, construction) { /* Not used. */ }
GeoScriptable.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="10" value="' + this.name + '" /></span><br/>');
place.append(
'<span class="geoItemCaption">Object definition: </span>' +
'<textarea id="script-' + idNum + '" rows="10" cols="50" >' + this.script + '</textarea>');
place.find('input, select, textarea').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoScriptable.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var scriptStr = content.find('textarea#script-' + idNum).val();
return new GeoScriptable({'name' : name_Str, 'script' : scriptStr});
}
}
{ // GeoRectangle // TODO to JXG.
/**
* Constructor for geometric rectangle object.
*/
var GeoRectangle = function(params) {
params = $.extend( {
'p1' : null,
'p2' : null,
'p3x' : null,
'p3y' : null,
'l1' : null,
'dash' : 0,
'name' : null,
'showName' : true,
'visible' : true,
'color' : '#00f',
'showGeneratedPoints' : true
}, params);
this.type = 'Rectangle';
this.p1 = params.p1;
this.p2 = params.p2;
this.p3x = (params.p3x == 'null' ? null : params.p3x);
this.p3y = (params.p3y == 'null' ? null : params.p3y);
this.dash = params.dash;
this.color = params.color;
var n;
if (params.l1 != null) n = parseInt(params.l1);
else n = popNewGlobalIndex(6);
this.l1 = n;
this.l2 = n + 1;
this.l3 = n + 2;
this.l4 = n + 3;
this.p3 = n + 4;
this.p4 = n + 5;
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.showGeneratedPoints = params.showGeneratedPoints;
}
/**
* CSS style defining the icon representing this type.
**/
GeoRectangle.prototype.iconCSS = 'rectangleBtn';
GeoRectangle.prototype.updateSceneData = GeoRhombus.prototype.updateSceneData;
/**
* Convert a GeoRectangle to JessieScript.
*/
GeoRectangle.prototype.asJessieScript = function() {
var s = "l" + this.l1 + "=[" + this.p1 + " " + this.p2 + "]" + (this.visible ? " nolabel" : " invisible") + ";\n";
s += "l" + this.l2 + " = |_(" + this.p2 + ", l" + this.l1 + ") invisible;\n";
s += "l" + this.l4 + " = |_(" + this.p1 + ", l" + this.l1 + ") invisible;\n";
s += "P" + this.p3 + "(l" + this.l2 + ((this.p3x != null) && (this.p3y != null) ? ', ' + this.p3x + ', ' + this.p3y : "") + ")" + (this.visible && this.showGeneratedPoints ? "" : " invisible") + ";\n";
s += "[" + this.p2 + " P" + this.p3 + "]" + (this.visible ? "" : " invisible") + ";\n";
s += "l" + this.l3 + " = ||(P" + this.p3 + ",l" + this.l1 + ") invisible;\n";
s += "P" + this.p4 + "=l" + this.l3 + "&l" + this.l4 + (this.visible && this.showGeneratedPoints ? "" : " invisible") + ";\n";
s += "[" + this.p1 + " " + this.p2 + "]" + (this.visible ? "" : " invisible") + ";\n";
s += "[P" + this.p3 + " P" + this.p4 + "]" + (this.visible ? "" : " invisible") + ";\n";
s += "[P" + this.p4 + " " + this.p1 + "]" + (this.visible ? "" : " invisible") + ";\n";
return s;
}
GeoRectangle.prototype.asConstruct = function(board, construction) { /* Not used. */ }
GeoRectangle.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" type="text" size="5" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show generated points: </span>' + '<span class="geoProperty"><input id="showGeneratedPoints-' + idNum + '" type="checkbox"' + (this.showGeneratedPoints ? ' checked="checked" ': '') + '/></span><br/>');
place.append('<span class="geoItemCaption">First point: </span>' + '<span class="geoProperty"><input id="firstPoint-' + idNum + '" type="text" size="5" value="' + this.p1 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Second point: </span>' + '<span class="geoProperty"><input id="secondPoint-' + idNum + '" type="text" size="5" value="' + this.p2 + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point x: </span>' + '<span class="geoProperty"><input id="thirdPointX-' + idNum + '" type="text" size="5" value="' + this.p3x + '" /></span><br/>');
place.append('<span class="geoItemCaption">Third point y: </span>' + '<span class="geoProperty"><input id="thirdPointY-' + idNum + '" type="text" size="5" value="' + this.p3y + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.append('<input id="nParam-' + idNum + '" type="hidden" value="' + this.l1 + '"/>');
place.append('<span class="geoItemCaption">Line style: </span><select id="' + 'dashSelect-' + idNum + '"></select>');
var dashSelect = place.find('select#dashSelect-' + idNum);
for (var i = 0; i < 7; ++i)
dashSelect.append('<option value="' + i + '"' + (this.dash == i ? ' selected="selected" ': '') + '>' + dashStr[i] + '</option>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoRectangle.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var visible = content.find('input#visible-' + idNum).is(':checked');
var showName = content.find('input#showName-' + idNum).is(':checked');
var p1 = content.find('input#firstPoint-' + idNum).val();
var p2 = content.find('input#secondPoint-' + idNum).val();
var p3x = content.find('input#thirdPointX-' + idNum).val();
var p3y = content.find('input#thirdPointY-' + idNum).val();
var showGeneratedPoints = content.find('input#showGeneratedPoints-' + idNum).is(':checked');
var nParam = content.find('input#nParam-' + idNum).val();
var dash = parseInt(content.find('select#dashSelect-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
return new GeoRectangle( { 'p1' : p1, 'p2' : p2, 'p3x' : p3x, 'p3y' : p3y, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'l1' : nParam, 'dash' : dash, 'color' : color, 'showGeneratedPoints' : showGeneratedPoints } );
}
}
{ // GeoGlider
/**
* Constructor for geometric glider object.
*/
var GeoGlider = function(params) {
params = $.extend( {
'parent' : null,
'x' : null,
'y' : null,
'size' : 3,
'name' : null,
'showName' : true,
'visible' : true,
'fixed' : false,
'color' : '#0f0'
}, params);
this.type = 'Glider';
this.size = params.size;
this.parent = params.parent;
this.x = (params.x == 'null' ? null : params.x);
this.y = (params.y == 'null' ? null : params.y);
this.name = params.name;
this.showName = params.showName;
this.visible = params.visible;
this.color = params.color;
this.fixed = params.fixed;
}
GeoGlider.prototype.nameStr = function(construction) {
if (this.showName) {
var result = this.name;
for (var property in this) {
result = result.replace(new RegExp('%' + property + '%', 'g'), this[property]);
}
return result;
} else return '';
}
/**
* CSS style defining the icon representing this type.
**/
GeoGlider.prototype.iconCSS = 'gliderBtn';
GeoGlider.prototype.updateSceneData = GeoPoint.prototype.updateSceneData;
/**
* Convert a GeoGlider to JessieScript.
*/
GeoGlider.prototype.asJessieScript = function() { return ""; /* Not used. */ }
GeoGlider.prototype.asConstruct = function(board, construction) {
/* Not used. */
var glider;
if ((this.x != null) && (this.y != null))
glider = board.create('glider', [this.x, this.y, this.parent], {
name : this.name,
size : this.size,
color: (this.fixed ? '#000' : this.color),
withLabel : this.showName,
visible : this.visible,
strokeColor: this.color,
fillColor: this.color,
fixed : this.fixed
});
else
glider = board.create('glider', [this.parent], {
name : this.name,
size : this.size,
color: (this.fixed ? '#000' : this.color),
withLabel : this.showName,
visible : this.visible,
strokeColor: this.color,
fillColor: this.color,
fixed : this.fixed
});
construction.points.push(glider);
construction[this.name] = glider;
if (this.showName) glider.label.content.setText(this.nameStr(construction));
}
GeoGlider.prototype.addOptionsDialog = function(place, idNum, boxnum, editable) {
place.append('<span class="geoItemCaption">Label: </span>' + '<span class="geoProperty"><input id="name-' + idNum + '" size="5" type="text" value="' + this.name + '" /></span><br/>');
place.append('<span class="geoItemCaption">Parent name: </span>' + '<span class="geoProperty"><input id="parent-' + idNum + '" size="5" value="' + this.parent + '" /></span><br/>');
place.append('<span class="geoItemCaption">Visible: </span>' + '<span class="geoProperty"><input id="visible-' + idNum + '" type="checkbox"' + (this.visible ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Fixed: </span>' + '<span class="geoProperty"><input id="fixed-' + idNum + '" type="checkbox"' + (this.fixed ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Show label: </span>' + '<span class="geoProperty"><input id="showName-' + idNum + '" type="checkbox"' + (this.showName ? ' checked="checked" ': '') + ' /></span><br/>');
place.append('<span class="geoItemCaption">Size: </span>' + '<span class="geoProperty"><input id="size-' + idNum + '" type="text" size="5" value="' + this.size + '"/></span><br/>');
place.append('<span class="geoItemCaption">x-coordinate: </span>' + '<span class="geoProperty"><input id="xCoordinate-' + idNum + '" size="5" value="' + this.x + '" /></span><br/>');
place.append('<span class="geoItemCaption">y-coordinate: </span>' + '<span class="geoProperty"><input id="yCoordinate-' + idNum + '" size="5" value="' + this.y + '" /></span><br/>');
place.append('<span class="geoItemCaption">Color: </span>' + '<span class="geoProperty"><input id="color-' + idNum + '" type="text" size="8" value="' + this.color + '" /></span><br/>');
place.find('input, select').bind('keypress.geoeditor', function(event) { enterKeyUpdate(event, boxnum, editable); })
.bind('blur.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('input:checkbox, input:radio').bind('click.geoeditor', function(event) { updateScene(boxnum, editable); });
place.find('select').bind('change.geoeditor', function(event) { updateScene(boxnum, editable); });
}
GeoGlider.prototype.createFromDialog = function(content, idNum) {
var name_Str = content.find('input#name-' + idNum).val();
var parentStr = content.find('input#parent-' + idNum).val();
var showName = content.find('input#showName-' + idNum).is(':checked');
var size = parseFloat(content.find('input#size-' + idNum).val());
var visible = content.find('input#visible-' + idNum).is(':checked');
var fixed = content.find('input#fixed-' + idNum).is(':checked');
var x = parseFloat(content.find('input#xCoordinate-' + idNum).val());
var y = parseFloat(content.find('input#yCoordinate-' + idNum).val());
var color = content.find('input#color-' + idNum).val();
return new GeoGlider( { 'parent' : parentStr, 'x' : x, 'y' : y, 'size' : size, 'name' : name_Str, 'showName' : showName, 'visible' : visible, 'color' : color, 'fixed' : fixed } );
}
}
{ // GeoScene
/**
* Constructor for geometric scene.
*/
var GeoScene = function(params) {
params = $.extend( {
'objects' : [],
'boundingBox' : [12.0, 2.3, 0.8, 12.3],
'description' : '1',
'name' : 'Scene',
'showGrid' : false,
'isStatic' : false,
'allowControls' : true
}, params);
this.type = 'Scene';
this.objects = [];
for (var i = 0; i < params.objects.length; i++) {
this.add(this.dataToObject(params.objects[i]));
}
this.name = params.name;
this.boundingBox = params.boundingBox;
this.description = params.description;
this.showGrid = params.showGrid;
this.isStatic = params.isStatic;
this.allowControls = params.allowControls;
}
/**
* Adds the given object 'obj' to the scene.
*/
GeoScene.prototype.add = function(obj) {
this.objects[this.objects.length] = obj;
}
/**
* Constructs a geometric object from a JSON object.
*/
GeoScene.prototype.dataToObject = function(data) {
switch(data.type) {
case 'Point' : return new GeoPoint(data); break;
case 'Line' : return new GeoLine(data); break;
case 'Axis' : return new GeoAxis(data); break;
case 'Image' : return new GeoImage(data); break;
case 'Intersection' : return new GeoIntersection(data); break;
case 'RegularPolygon' : return new GeoRegularPolygon(data); break;
case 'AssociatedLine' : return new GeoAssociatedLine(data); break;
case 'Scriptable' : return new GeoScriptable(data); break;
case 'Circle' : return new GeoCircle(data); break;
case 'Triangle' : return new GeoTriangle(data); break;
case 'Sector' : return new GeoSector(data); break;
case 'Square' : return new GeoSquare(data); break;
case 'Angle' : return new GeoAngle(data); break;
case 'Parallelogram' : return new GeoParallelogram(data); break;
case 'Label' : return new GeoLabel(data); break;
case 'Rhombus' : return new GeoRhombus(data); break;
case 'RestrictedTriangle' : return new GeoRestrictedTriangle(data); break;
case 'Trapezoid' : return new GeoTrapezoid(data); break;
case 'Rectangle' : return new GeoRectangle(data); break;
case 'Polygon' : return new GeoPolygon(data); break;
case 'Glider' : return new GeoGlider(data); break;
case 'ParametricCurve' : return new GeoParametricCurve(data); break;
}
return data;
}
/**
* Convert a scene to JessieScript.
*/
GeoScene.prototype.asJessieScript = function() {
var s = "";
if (this.objects != null)
for (var i = 0; i < this.objects.length; i++)
s += this.objects[i].asJessieScript();
return s;
}
}
{ // Global index handling.
// Initialize global index variable for object names.
var globalIndex = 0;
var popNewGlobalIndex = function(incCounter) {
var result = globalIndex;
globalIndex += incCounter;
return result;
}
}
{ // List of different object types and their constructors.
// List of all object type labels.
var objTypes = ['Point', 'Line', 'Axis', 'Circle', 'Triangle', 'RestrictedTriangle', 'Square', 'Angle', 'Parallelogram', 'Label', 'Rhombus', 'Trapezoid', 'Rectangle', 'Glider', 'AssociatedLine', 'RegularPolygon', 'Sector', 'Intersection', 'Image', 'ParametricCurve', 'Scriptable'];
// Mapper between type labels and their constructors.
var objClasses= new Object();
objClasses.Point = GeoPoint;
objClasses.Image = GeoImage;
objClasses.Axis = GeoAxis;
objClasses.Line = GeoLine;
objClasses.Circle = GeoCircle;
objClasses.Triangle = GeoTriangle;
objClasses.Scriptable = GeoScriptable;
objClasses.Angle = GeoAngle;
objClasses.Label = GeoLabel;
objClasses.Parallelogram = GeoParallelogram;
objClasses.Rhombus = GeoRhombus;
objClasses.Trapezoid = GeoTrapezoid;
objClasses.Rectangle = GeoRectangle;
objClasses.Glider = GeoGlider;
objClasses.AssociatedLine = GeoAssociatedLine;
objClasses.RegularPolygon = GeoRegularPolygon;
objClasses.Polygon = GeoPolygon;
objClasses.Square = GeoSquare;
objClasses.RestrictedTriangle = GeoRestrictedTriangle;
objClasses.Sector = GeoSector;
objClasses.Intersection = GeoIntersection;
objClasses.ParametricCurve = GeoParametricCurve;
var objCreateGuide = new Object();
objCreateGuide.Point = ['Click to add a point to the given location.'];
objCreateGuide.Image = ['Click to add an image to the given location.'];
objCreateGuide.Axis = ['Click to add an axis to the given location.'];
objCreateGuide.Line = ['Select the first point of the line.', 'Select the second point of the line.'];
objCreateGuide.Circle = ['Select the center point of the line.', 'Select a point to set the circle radius.'];
objCreateGuide.Triangle = ['Select the first point of the triangle.', 'Select the second point of the triangle.', 'Select the third point of the triangle.'];
objCreateGuide.Scriptable = ['Add a scriptable object.'];
objCreateGuide.Angle = ['Select the point defining the right border of the angle.', 'Select the corner point.', 'Select the point defining the left border of the angle.'];
objCreateGuide.Label = ['Click to add a label to the given location.'];
objCreateGuide.Parallelogram = ['Select the first point of the parallelogram.', 'Select the second point of the parallelogram.', 'Select the third point of the parallelogram.'];
objCreateGuide.Rhombus = ['Select the first point of the rhombus.', 'Select the second point of the rhombus.'];
objCreateGuide.Trapezoid = ['Select the first point of the trapezoid.', 'Select the second point of the trapezoid.', 'Click the third point of the trapezoid.'];
objCreateGuide.Rectangle = ['Select the first point of the rectangle.', 'Select the second point of the rectangle.'];
objCreateGuide.Glider = ['Click an element to add a glider to the given location.'];
objCreateGuide.AssociatedLine = ['Select a point of the new line.', 'Select a circle or a line related to the association.'];
objCreateGuide.RegularPolygon = ['Select the first point of the regular polygon.', 'Select the second point of the regular polygon. The polygon is created to left side of the line, when viewed from the first point towards the second selected point.'];
objCreateGuide.Polygon = ['Select the first point of the polygon', 'Select the next point of the polygon.'];
objCreateGuide.Square = ['Select the first point of the square.', 'Select the second point of the square.'];
objCreateGuide.RestrictedTriangle = ['Select the first point of the triangle. The type of restriction is chosen afterwards.', 'Select the second point of the triangle.'];
objCreateGuide.Sector = ['Select the corner point of the sector.', 'Select the point defining the radius of the sector.', 'Select the point defining the angle of the sector.'];
objCreateGuide.Intersection = ['Select the first element of the intersection.', 'Select the second element of the intersection.'];
}
{ // General elements.
var findTypeByName = function(typeStr, name_Str, construction) {
var j = -1;
do ++j; while ((j < construction[typeStr].length) && (name_Str != construction[typeStr][j].name));
var item = null;
if (j < construction[typeStr].length) item = construction[typeStr][j];
return item;
}
var findPointByName = function(name_Str, construction) {
var j = -1;
do ++j; while ((j < construction.points.length) && (name_Str != construction.points[j].name));
var p1 = null;
if (j < construction.points.length) {
p1 = construction.points[j];
}
else {
j = -1;
do ++j; while ( (j < construction.intersections.length) && (name_Str != construction.intersections[j].name) );
if (j < construction.intersections.length) p1 = construction.intersections[j];
}
return p1;
}
var dashStr = [
"Solid line",
"Dotted line",
"Small dashes",
"Normal dashes",
"Long dashes",
"Med./big dashes, large gaps",
"Med./big dashes, small gaps"
];
}
}
{ /** jQuery Plugin interface **/
var methods = {
'init' : function(params) {
// call handler.
params = $.extend( {
'editable' : true,
'width' : '100%',
'height' : '500px',
'mode' : 'free',
'name' : 'Scene',
'isSquare' : false,
'browsingMode' : 'free',
'scenes' :
[
{
'description' : "1",
'allowControls' : true,
'showAxes' : true
}
]
}, params);
$(this).data('sendUpdateTrigger', true);
/*
* Free mode uses tabs for numbered examples and balls
* for everything else.
*/
if (params.browsingMode == 'free') {
var i = 0;
var useTabs = true;
do {
useTabs = useTabs && (((i + 1) + '') == params.scenes[i].description.trim());
++i;
}
while (useTabs && i < params.scenes.length);
if (!useTabs) params.browsingMode = 'tabless';
}
if (params.mode == 'square') params.width = params.height;
else if (params.mode == 'tiny') {
params.width = '200px';
params.height = '150px';
}
else if (params.mode == 'small') {
params.width = '400px';
params.height = '300px';
}
else if (params.mode == 'medium') {
params.width = '512px';
params.height = '384px';
}
else if (params.mode == 'large') {
params.width = '640px';
params.height = '480px';
}
else if (params.mode == 'full') {
params.width = '100%';
params.height = '500px';
}
if (params.isSquare) params.width = params.height;
return this.each( function() {
init($(this), params);
});
},
'setContent' : function(data) {
return this.each( function() {
setGeoSceneData($(this).data('boxnum'), data);
addTabs($(this).data('boxnum'), $(this).data('editable'));
});
},
'getContent' : function() {
//var oldvalue = $(this).data('sendUpdateTrigger');
//$(this).data('sendUpdateTrigger', false);
var arr = new Array();
this.each( function() {
var boxnum = $(this).data('boxnum');
var sceneNum = parseInt($('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).attr('tab'));
//setScene(boxnum, sceneNum, $(this).data('editable'));
//$('div#previewBox-' + boxnum).find('.currentjessiebutton').eq(0).click();
arr[arr.length] = getGeoSceneData(boxnum);
});
//$(this).data('sendUpdateTrigger', oldvalue);
return arr;
},
'addElement' : function(data) {
data = $.extend( {
'state' : -1,
'toolType' : GeoTool.TT_CREATE_POINT,
'dx' : 0,
'dy' : 0,
'ux' : 0,
'uy' : 0,
'temp' : [0, 0, 0],
'type' : 'Point',
'update' : true,
}, data);
return this.each( function() {
var tool = new GeoTool(data);
var obj = initNew($(this).data('boxnum'), data.type, tool);
insertConstruct($(this).data('boxnum'), obj, $(this).data('editable'), data.update);
// Added to enable tutorial mode.
$('div#previewBox-' + $(this).data('boxnum')).trigger('geoeditor_objectCreated', obj);
});
},
'update' : function(data) {
return this.each( function() {
updateScene($(this).data('boxnum'), $(this).data('editable'));
});
},
'setSceneOptions' : function(data) {
return this.each( function() {
var sceneArr = getGeoSceneData($(this).data('boxnum'));
for (var i = 0; i < sceneArr.length; ++i) {
var sceneParams = data[i];
sceneParams.objects = sceneArr[i].objects;
sceneParams.description = sceneArr[i].description;
sceneParams.name = sceneArr[i].name;
sceneArr[i] = new GeoScene(sceneParams);
}
setGeoSceneData($(this).data('boxnum'), sceneArr);
setScene($(this).data('boxnum'), 0, $(this).data('editable'), true);
});
},
'editDone' : function() {
return this.each( function() {
$(this).trigger('geoeditor_changed');
});
},
'getSceneOptions' : function() {
var arr = new Array();
this.each( function() {
var current = getGeoSceneData($(this).data('boxnum'));
for (var i = 0; i < current.length; ++i)
delete current[i].objects;
arr[arr.length] = current;
});
return arr;
}
}
$.fn.geoeditor = function( method ) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.geoeditor' );
return false;
}
};
}
})(jQuery)
//}}}
//{{{
// Added so it can be used without TiddlyWiki.
if (typeof config == 'undefined') {
var config = new Object();
config.macros = new Object();
}
config.macros.geograph = {
/******************************
* Show geoeditor
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var geoname = '';
var editable = false;
var options={};
var geoeditoralign = "geoeditorcenter";
if (params.length > 0){
geoname = params[0];
}
if (params.length > 1){
var sizeParam = params[1];
if(sizeParam.substr(sizeParam.length-1) === "R" ){
geoeditoralign = "geoeditorright";
sizeParam = sizeParam.substr(0,sizeParam.length-1);
} else if( sizeParam.substr(sizeParam.length-1) === "L"){
geoeditoralign = "geoeditorleft";
sizeParam = sizeParam.substr(0,sizeParam.length-1);
} else if( sizeParam.substr(sizeParam.length-1) === "C"){
sizeParam = sizeParam.substr(0,sizeParam.length-1);
}
if(sizeParam === "tiny" ||sizeParam === "small" ||sizeParam === "medium" ||sizeParam === "large" ||sizeParam === "full" ){
options.mode=sizeParam;
}else if(sizeParam.substr(0,2)==="sq"){
options.mode="square";
options.height=(sizeParam.substr(2) === parseInt(sizeParam.substr(2))+''?sizeParam.substr(2)+"px":"400px");
}else if(sizeParam.match(/w[0-9]+h[0-9]+/)){
var posh = sizeParam.indexOf("h");
options.width = sizeParam.substr(1,posh-1)+"px";
options.height = sizeParam.substr(posh+1)+"px";
}
}
if (params.length > 2){
editable = (params[2] === 'author');
}
var grapheditordiv = '{{grapheditor{\n}}}';
wikify(grapheditordiv, place, null, tiddler);
if(editable){
options.mode= "full";
}
options.editable= editable;
var geoeditors = (tiddler ?DataTiddler.getData(tiddler, 'geoeditors',[]):[]);
if (geoname !== ''){
var editor = jQuery.extend(true, [], geoeditors[geoname]);
if (editor.length > 0){
options.scenes = editor;
}
}
jQuery(place).find('.grapheditor').last().addClass(geoeditoralign).attr('geoeditor',params[0]).attr('geoeditorsize',(params.length > 1?params[1]:'full')).geoeditor('init', options);
if (editable && params[2] !== 'author'){
jQuery(place).find('.grapheditor').bind('geoeditor_changed', function(e){
var geoeditors = DataTiddler.getData(tiddler, 'geoeditors', {});
var geodata = jQuery(this).geoeditor('getContent');
geoeditors[geoname] = geodata[0];
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(tiddler, 'geoeditors', geoeditors, {});
config.options.chkAutoSave = autosavestatus;
});
}
}
}
//}}}
!usage
{{{[img[h1line.png]]}}}
[img[h1line.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-addelem.png]]}}}
[img[icon-addelem.png]]
!notes
Element add icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIzSURBVDiNlZVNaxNRFIbfc2coDRNSE6hUmiCVFGpbGCkS3dh/Yd2pSLaudOVSl3bpshuXltL+AhfFhaWgELH1KxXFtFFoMyR2aJL7cVxMMknoJDF3uDDDfc497zvncC8xM1b2KRsXyTXNyiWyLIwwmLW2yC6cGi+/Ps9Fur2HbNxK7dxLr6ayTo4INMp+YDCK/i6/LD2unOrKTevGw+Tm3czq3KyTozYy2gRSY9OUiS3EPv1949qalTvjuKTRjFSwX/uMd14BSissJV24ycVIbsZxSbNybSJhaai+ll6VtlDyj9BUTXyofMTz60/7skTCsgGGhuwLSe6sSSMHsgDDZgD97AYI97wPZgEbwJCsvWMY27IcZP1xdojXx7toqAakVlBKoiprIew1q3j09hmUkpBagQA8WFjBtcn5UKMNAKqV9av/E56sQWoJqYJpuGPZsMFJ3QvXpJbYKb/H4uRstEKG+W/r7cEwXf81LEqg8LJzEb/O/qBODShSUCRxoqthsCBCanwCUkmoluWlS3NhfFdRggzTsQu4k7nVo+DF3iaOZbA+MRbHk9z9cyq7Kz+0D88HD+lDoFOUaKS3DwexAIY3tkWd08cSYnhjMxsdQNHH1nL6Kr55R1BaI5ucGmCZwWy0LUgUDv0vy1POlcgd04kE0olE+N1P4W//OwsSBVE3fn67tFEp+wfMMOCRH4Oyf8DbpY1K3fh5al8B48JZM6xcIjHiFWC0ILtQN35+fZ6L/wDTpVZ/H9feUwAAAABJRU5ErkJggg==
!usage
{{{[img[icon-calculator.png]]}}}
[img[icon-calculator.png]]
!notes
Icon for calculator
!type
image/png
!file
!url
!name
icon-calculator.png
!author
pesasa + OCAL
!source
emath
!license
pd
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMHSURBVDiNnZXfahtHFIe/mZXWa8leITlSMY4pdQytgyMRahyTpn6J0jfoI5Q+ROl1r/IEKSX0ulBC0ovYbSkmxMakJRcxFOFKlbT/tDs7e3ohW01stcGdm4HhnG9+55yZc5SIoL45XK/P6ft5IR0H5XCFZRFb0urgr7T4TD69+ZviwfP1hus8/erD643tpapSV6EBAuz3Ivn8l5N+P7M7qv7d0aMvb6/ubi9VFcCLH3/gz5cviOP4P0HVhQXW2rdp3dqCM+gXv756XMqtdDqNqspkYpikKWbwhO0PNI5bY5xXwPEpHB+xKXM6Ion6/Pysz8rGLc79Oo2qyq10SlopJ5d/bi4A5XhcazUYxXM0l5qMYhckJ08T3llS/JHGqMJQAOY1X62UU5ILhwUwzhf46ZlBHAdRAxwFIglZPOLVicWMY3JxLwEFKDEDuNi4SQxgLyTOhbCY7K1VLgGZCRRYOT5m4+iIJ/fu8XB/n9XVVay1nJ6esrW1xd7eHpubm1zbaF8GCkwTe66wHIYsDAaQJIRhSBRFjMdjRqMRSZLQ7/cJw5Digu/skAW+932+brW4U6ng+z6e51EqlciyDNd18TyP+fl5CpkR8qyiZFlGr9cjz3OSJCGOY4wxRFFEnuekaUqaphRnAt5aFIByuYyIoJRCa43WGnX2j0RkamvfVhSRCczzPMrlMo7j4LouWmtc18VxHJRSuK77LyHLZYVJkhAEAePxmCAIiOOYLMsIwxBjzDQVF9Mlcqbw9UpZgcXFRWq1GpVKhWazie/7GGMwxuB5Hr7vU61WsfKm78yQC6DX6zEYDAiCgMPDQ7TWGGPodrsEQUC322U4HM5+2AViM4HztqWA5eVlgiCgXq/TbrdZWVnBWovnedTrddbW1mg2m28ABSgmvVEdHA+i3Ru1SfvStqDRbLHTbAFw5+5H09vfXbsBwN2PdwFIjZkCfx9GopU6UDx4vl4tO08/ef96473a/2uwL4eRfHt80o+M3VHnI6Ba1vdzkY6+4ggoEFtS6iAykxHwNzgnqMj7ejCNAAAAAElFTkSuQmCC
!usage
{{{[img[icon-checksol.png]]}}}
[img[icon-checksol.png]]
!notes
Check solutions icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJrSURBVDiNlZXNS5tBEMaf3fdN0ihok2gwqBVjoCUQggQ05FBEj2oPggexgooQ8JJL/goJSA6Chx5zsYVePIl4suAHBNF4MtJCv/KStpFoFIO7Oz3ERFKtvlmY28xvZ57dmWFEhA+M+WwOxzslRJBpmoYGDkkpua4fls/OFiaJTtl7wGdzOnfDiYTTPTDAwFgjPIAI+f192o3HC+VCIay9dTg+hhOJV+7BwQZJd6e5s5M5/H67sb0d1JUQQXcoxCClaYCSEsbWFpRhoG10FM9cLrhDIaaECOqMcw1KmYbdXF3hazyOnnQaeZ8P2sQEqskwzjW9cqV54LdkEp3pNEpNTbDFYrDYbHXxFaDJcn9ubuL5+joIwPnUFF7099+LNQ0s5XIQq6uwCoFcJALvzMyDcTqIngYS4cfyMjoMA2ceDzpisYdlIoIpDT+nUnDt7ODaaoUlGkVTW9t/Yx4sWUkJftswv4+PwdfWwACUxsfRF4k8WhGvAW/tYGkJ+7OzKJyc4KZUwq+VFdgvL/EnEEDv3Fyd7z37N8N8Ngva2IATwPdUCnpLC1qzWVy6XOhYXARn7Em96zR0e7344vEAuRyse3uwKYUbzmGZnkZLV5ep/8prrywloBTsfj8AwCoENCJcDw+je2Tk8VKrRnRfw66xMVzb7QCAoteLvvl5c7CqhqSUhBCoji1ndzcuolGIiwu8HBqCxWIx10lEIKWkznX9MH909NodCNTGV08kcudoss/zmQxxXT/UJsrlT8bBwbSjt9fe3N7e+EwkQj6Tod1kslA+P3/DaiugtbWyAjhvbAUoVVkBxeLCJNHpX0UbUcmtNwHtAAAAAElFTkSuQmCC
!usage
{{{[img[icon-comment-course.png]]}}}
[img[icon-comment-course.png]]
!notes
Icon for course comments.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-comment-hide.png]]}}}
[img[icon-comment-hide.png]]
!notes
Icon for teacher comment hide
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAUogAAFKIBqj7LWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASISURBVEiJxZZdaBRXFMd/c2fMmm+1VWykFpESGqgGHxQ3RgmWYM0HKG0laagGSsFYhJZSK+2DrfiyFXyQgkJ98cW8hJYQX2ygDxqIkaBxN6ttNmmjG5MS89Emu8luZub0wd1xZzfqqik9cOHOOff+f3PuvXPuaCLC/2HGUooFNe1zoA8o0KDnLZHRrMGapm0AaoAtwKpKWFkIxmZY4YOQBYsu0VfwZhOUzYPpAb0DBss0rQu4CVwWkZCLk7rUmqYdUUqdtm17eUlJibk9N1d9OziobEABZ9avt3uKizPAO6antZb795WWeI4rxTcbN9p90ag9MjJiKKUWbNv+WkS+dyaJCAn4+4DU1tbaw8PDIiIyf+eOBMBpQxUVkm6znZ3Sv2yZa9x0a6sTD4fDsm/fPptHK9Xs8BLQHF3XH27bts2yLMslHNq0ySUavX7dic319UmwqMgVHzt+POPlbNuWyspKSyn1D5CXCt4CSFtbW8akcZ/PJXz/wAEREYnfuyd3S0pcsVter9TV1MjevXszdK5cuSKJrHemgg8BEgqFMibEw2EJKOWI9xuGzN26JQNlZS5oYMMGecXjEUDa29szdMbGxpLgIyKCSmz1coD8/PyM07ps3Tryq6oenwnT5A+vl1gw6PhUcTGfGQYTsRhHjx6lrq4uQ8fj8TiSJA7rM21FU5Pr2Y5GHz8oRceuXfwyMEB5eTk+ny8byezARfv3o3JzF41NHjzIl+3t5Ofn09ramprZy4NVURGF9fUZ/pzqat67fBmAs2fPUlpamhUUsiyZsrBAfGgow/+gq4uHkQgNDQ00NzdnDYUsM/7r2DHmbtzI8L8aifDx6tWcO3fuuaBZgWc6Opg4c+aJ8U8Ng8In7P8LgxfCYUYOHXL50gu1Gh1l6sKFFwbHAKIpn4lYFuHGRqyJCccXAw4Dc2kiD0+dQmKxp4Li8Xiya6aC/QC3b992Bo6fOEH06lXX5F6vl2vAjytXuvwL4TCT588/Fez3+5PdAOCUTI+u61MVFRWWZVky29npKpMBkMGtW+XvqSnp7u6WWCwmf+7Z44rfXbtWrEgko1QmL4mqqipbKTULFDi1OgH/EJCPamvt4Jo1LtH+nByZ7+93iS2MjMidVavc1+GlS5mXzPi4NDY2Juv0J0me60dA17Qvzmuab7uIRoqtOXmS0fp6WlpaJB6POxO2Tk5qhwcHNYCBggJOl5bacfX4vE5PT9uhUEgHLBH5TkROJmOuAuIHQ9Kgy8vLuVddze6dO62ZmZlx27b7krEbwGbY5IXXfpqd9Xf19j5I29oI0Av8LCJBVySZehDeCMC866rTdem5eFEKCwtNXdeHgNeT45NtADz9UP/ro5cm2+Z0AtDggoL0NDVJXl6eaRjG70DJ8wg/qzkbIrA6dSWGDYN32trseDz+m2maO0QkfRlfypw9VtAtjz5uwwaOmyZR8JumuVtEJp4s8YKWmr4fPrgGQ3tAdF2/DqxYyuVNba7PCUDTtB+At4EaEZlZ8kwTtth9LMC7IhL5r6DAohnnikj6PbDk9i/pJ9tHN4+4gAAAAABJRU5ErkJggg==
!usage
{{{[img[icon-comment-show.png]]}}}
[img[icon-comment-show.png]]
!notes
Icon for teacher comment show
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAUogAAFKIBqj7LWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM/SURBVEiJxZe/T6tVGMc/748KWFkkuSENDtKBgYVcEhgqyg9DInYBdAAXy0AIEGLC4OCmgwnqQPgP2EkMwYWFQYZiIAioYWhvQqSBgvKr3rRg3/frQF9SoOUWKN4nOcmb9znnfM7zfU7Oc44hiddh5muhAvbNH4ZhvAt8DDwH3n7k/CfAOvCTpNg1Tr7UhmGMmab5veu6lYFAIFtTU2M8hnp0dKREImGbpvmv67pfSfruyimJHPxTQOFw2N3Z2VG5bHd3V729vS4gIHLFy0HfsCzrr9bWVsdxnLJBPXNdV21tbY5pmmfAm/ng54Dm5uYeBVheXlY4HFZPT88t3+LionJRv58P/hxQLBZ7MHRjY0MVFRUCND8/f8u/v7/vgcfywSOA9vb2HgRNp9NqbGwUoImJiYJ9jo+PPfAXZQOPj48LUFNTkzKZzP8DXlhYECC/36/t7e2i/W6CH3VyJZNJhoaGAJiZmaGhoaHksY8CRyIRDg4OGBgYIBKJ3G9wqVInk0n19fVpaWlJkjQ9PS1A9fX1Oj09fWVKHpzjsbExAQoGg1pfX1dlZaV8Pp9WVlZeCS0EvlUkillzczMA8XicUChEJpNhamqKlpaW+0l8Q+oIoHg8XnTFiURCPp/PW7W6u7vlum5J0UqXqcqNHVfert4C2NzcLLrAQCDA8PAwAHV1dczOzmIYpRevra0t7/O3/IgrLMs6DoVCdxaJs7MzRaNRnZ+flxypdFkkOjo6XNM0/wHekre5cvDPAPX397vJZPJeE99lh4eHGhwc9GQe9ng3LwKTpml+K8kOBoPOyMiIPTk5iZeG0dFRXVxclHxJOzk5cWOxmAU4kr6W9I3nu7arJf1gGMYCEInFYl96OVxbW6Orq8tJpVKHrutulJxYeAmsAT9K+uOaxws9vwGfAFpdXVU0GlV1dXXWsqwXwDuF+j+kFTsy2/1+v5NKpejs7HTS6fQLx3Hek/TnPaK92wqtxrbt7draWlVVVTm2bf8OPCtXpFeqFpD5GblDwrbtX4GackOLSf0BgGVZv2Sz2XZJf5dN3jwrBG4HfnYc50NJJ08BhQIvCS5l/kjSy6eCwo2XBIBhGFWS0k8JBfgP7uEV9xJgGzsAAAAASUVORK5CYII=
!usage
{{{[img[icon-comment.png]]}}}
[img[icon-comment.png]]
!notes
Icon for page commenting tool.
!type
image/png
!file
./images/icon-comment.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-discussion.png]]}}}
[img[icon-discussion.png]]
!notes
//none//
!type
image/png
!file
./images/icon-discussion.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-edit.png]]}}}
[img[icon-edit.png]]
!notes
Icon for edit
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANqSURBVDiNlZV/TJR1HMdf3+c5epyHIg+xyt0GGjir1YGEqay2uoY0VzmXrprDcpe5ueU/zM2NRnOzdDv7saQ1gxVNosmU/kj7p/VrRzKyUzIEBIHFoQLdwYHPHXf3PM+3P05uOAjGe/v89d33te/3837v8xFSSkTztYJsTakzbelWESpLkIW0HIroGI/bXrnz0T7Bmc4C/T61zVfi0jfmOIVYCg2QQHvIkFV/BsPhhLVJydaUuuMbXHqJ7hSWBHORujk8zKl3D9B3vQdTgiWhRHeK4xtceram1CmmJd1u3SkSEharziuXOPlWJS/nvknriWN8UuUlmkiSkODWncK0pNuhCKGacvGvtZ1vpP3bz9nzdiPrVRdFa7/kSn8rH+17g4P1pxFCoAihKhJIyoWr5dPDjLed5JtaD57i0/yudjFIlKK1Zexa9zrNPh9JmeqnwgLAuGlRX7WDx5Zf5cihCkRyiJXRo+zIK+Jfzc8I0zzn3sbN1p+JxROwEHByaorPvGXsLc9kz65SiHVC6GuwowhMSrO20Uk301is0u7neudVABySVMNnayz4D98deoEPqz0UrsmBO60w+ePdkEAoArdDJoVsp+rMs6ypKCLPXYL8pRvHzAtnNBDwc/FjLw0ntqOv0iDyPRiX0uejYRibANsGX+NtCl/z8HjF7jTDIWcBe9r81FZu5Wz9q+hZKoSbYLo3HeBbYzA+BfEkHG1YTvHBFgo2lafvzzHl17r3eWdfOS0/9HO45gvik3dhEoZGUrA7MaipX8HGaj95T5Xf0/c5pvRfDvDKS0+wv/JJSkrL2P1eJrE4DN6CKQPCEaj5KoenfX+R+0jxHCMBFDkTkaSJsBMIy8CMR1iXr7HzRTf7P9CITsPwKBxpWs3ztdfIcuXPmwwpSZmSkNB+tglVkUSNMIo0sBKT5D8kyViWxW+BUc4FHqb8VABtxco5qZittMt/NPi4MThB9bGf8GzJoat3jIGhKQaCMfxdD7L3wt+o2rJ7EjEv0EZaCQmRsRB6jpPLfVFGMvLIXu9h9dbNbC7dQmbuA8xOw3ySgJ2ajaKjZ8J45sDF4P+OwsVeBXAjYkhFiA7FSNre5u5guHfCkDPzbSllSuidMGRzdzBsJG2vmFkBzgylzpTSrSxxBdhIyyFEh5FMrYD/APpnBu5BT58eAAAAAElFTkSuQmCC
!usage
{{{[img[icon-eye.png]]}}}
[img[icon-eye.png]]
!notes
Icon for eye / view
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAL+SURBVDiNrZVdaJN3FMZ///d9m5gmdGtq/GjSJqlJ0YoN3YXKBoI62M1gbLjVOeYmFEGHguClCI6x3cgudjPc3PBCYf2ww12IF3OjrOxT1EqMFNMS13RG0fi65m1j8r7v2YWx6/zYCO6Bc/XnPDznOef8jxIRMm+ohBZoPiqOnVJK16kDIo6jdGPMLd3p6xqQrLr8Ogk9EPw58u7hoD+xVqFUPXwggpX9VfLH9hedUnG9vmdd83DbO4dX+pNra0xSZ4AnGFa+ttW+mSs/pAxx7JQ/llLYlfqUPQR/LKXEsVOGUpqOaz8V2QMopekGCDjV/4UQBAMBnP8ut2rbnM9cpWtFjHPpcX66mOG9t17h5m2TeGQZhq6DgAGA/WSFIsIHn31FeuJ30uOThJe28OOFDKs62jk2fIbwkhY6YxEO7HwTgFrJjyq8dDXHp/2nGRy9yKwngOH1ImVB/qwSaY+Snb6BaZrkpgusW5NkeUuALFJTuMDDW+YMh44M8OWps/gXL8GTWMOi1hjhcCu7Nj1P4z0Lr66RTqcZHBykO/IsO1/djIELgDav0KmQy0/z+ckzfDPyCxs3v0g4Guflbb2Us5dxJ68w5/XyxfETRKNRTNOEOZP48hbaFjfVqnzQFLuKOTOLVbLIF27hCTTT29vLwNBJKnfv8tqu3XgaGjj17Vn+mJqiv7+fyfMjfP3RXuKtIcAF213QFKdCYwNEQ00Mf/8bW7a9TXd3N8lkkvc//oRcaRa3MofcKRIol8id+459WzYRX/rMI/7Pz6FHgw9PnEZ5G/H5fIyOjlK5V6anPcRzMwVWhYJ0tvcQbPKzojXEw97/PYe1h8y1ApeyU2x96QU6fHPs6KziNTzQkwAS/8z7l0WoeVihKxxk+OD2hVlgO09MfCwEDBHXue9Dnd/WY9hEXMdQmjZmTY9v8C/reCpGqzApStPGNLds9eVHhorW9QlBXBCpM1ys6xOSHxkqumWrT82fgEX+o+LaKaW0Ok+A6yjNGHPLVl/XgGT/Alx1b6i2I6+8AAAAAElFTkSuQmCC
!usage
{{{[img[icon-feedback.png]]}}}
[img[icon-feedback.png]]
!notes
Feedback icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANVSURBVDiNlZXBbhtVFIa/e2c8duzYSew2OE3cqE0KUkuxUqSoC1QWqOqCJULZIFZ9AoR4BBYVvEGfgKzKpitQYUFLKUURSRoaSCrFVVPcOI7tGceeufewGGeStiCRI12N5uie//z//HfuUSKCWlydHUvrm5GVqoNyOEYYxLhaLe327HX5+Pyfim9WZouec++rd6eK86WcUsdBAwS4v+PL57/WGo2+uazGbj26c2OucmW+lPvfWNZaet0uvd4+hdExtNbc3/Hli9+2fnQjI9VqMaf6Asu3v6Z8Mo3CoIkGT4MiQiuLshEag+tashlN1A6oTXxGuXKaajGnIiNVVyvlRBJ3niy84Or8+ECIAtzB8gCov/AJAmG6UgKEVjvL7a0moZwGQCvluAKEcigFMQDstfYRsaRch1zOo7EbUK+36XR6TFcKAAxnU/id3aReBu2ThBEFYgFhdfUZl+crrD2uEwQhKU/h+yGnyoVkj9Zgov2knlcBbQwLgOPAT/ee0O2GeJ7DRD7PuTNFhoZcdnbalIpZAJQKXwYUoH+QSBhCqZimVMyS8VwyGZeg2+fBwy3GRjOsPKqz8NGFuETCpP41yVoUiGHp921mzhZxHU3H7/LzgzrLq8+pTI6wv9/ng/enk8bwLwwPEq6NGW5sNth6usvGZpNPFi4y984buA5cqpYZyrhsP+8k5ml6/22KVhrE8ObsKJMTeT68OotSMjgBhiiK2Gv1qT1tUh4fAiDvtOgdYagPAEMBIxrEcuGtEqOFFMur2yAWawwjeZfvf9hg80mDS9Xx2EIxDEe1pD6WfORFbBroxdyB7+5sEgQ9giDk73pAZSpPeXwIrWyy51SuxXq7RWa4gMhA8oFLbTkB0gTA9/sUxzwynubsdImT700e6koMgYvnctx6eJfi3LWY4dFvuJeaAHkMQC7r8unCeV6NdqfPLyttnrXS7EYj+N4E7sz0EWMR05f4z2Vqjhvf3sUoj1B5RLgYlcbgYVSKSGdQpTOceHseJ5U6PCoDlTa+G9XSH03/ysxITqXHp+hf+zJxy3uNXxwWsPJy7q89X7RSS9oP7fXFtVpjvelLJGCOuSKB9aYvi2u1hh/a6+pgBORS+mYkUtXHHAEWMa5SS34Yj4B/AHF/wuuLghttAAAAAElFTkSuQmCC
!usage
{{{[img[icon-goemath.png]]}}}
[img[icon-goemath.png]]
!notes
Icon to settings panels goto e-mathcenter options.
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAACgElEQVQ4T3VTXUiTURj+JkFeeCUWRSVBZVEgeZPmXZNu8geidBehW7L8mS4SrSsLuqgkoiyyGiuJsiCIiOjHLZyWQaErraU0q0U3VkLgnFHod57Te3ZO3759rMPh4zs/z/s+z/O+x7bIsCTLpv1nvJ3gwQEtPKZFp7TYV56IZy1fgXVrbVXl3OO2aTzTmP6Bs5dZQxs74OUNXl7jQkERtBxunms2cSs4noDvBnsSYjqDJezHL2jtQHaeKYT5xstRnDqXAWa+M/4eqymnZGEc9IcYUTWWlPlRkF/043SPTt8790CZ5en4BJbmJVXIdWgY+z0pnr19cB9iRATgRH8qBsKXVWJzMfPfFAnosgKTPVtK2GxCgMn82iZGJlnGwHPsqWME2FCE7zN40P8PXOVA9xVF2NmM0p2ULzVeRxjtECw3n5+5AIpOZ+E3Sc2Dw+Lg24zYuv9YxH4YUNjIJKqdqkJULUlNjlEJrnCgpEztbrML8J9FUMTdteKfZuF2BIZSRkrwrbssexnX6NjdKtY/4+r2gg5fL6d5/TaiMWu1JdheifM+JsDSHiUjh3/4bM1jMY/S1jUJ6QLsahbhia2sXn1L5mwyRGCQ1R/UpW0CvH6rut3YppgfPZmhz8hU72EcOQajcQWY5lhEUJ3/JcTInVUb0d7JpPjjXSivQbEdL0bSFCnwrmqVnErc40dhaeoN5eZjXyMLDjFz9adnF6h/FZhSGX0itZEF7yYx91u3GEDt1dWNT8k+12TTyelpB7WqxVtj+SqMlg44XNSeak+bm4ehk/BkOC07T7BLV0W16Uv/e51sZQF2VODps7TQ4lWRmGt9aToNLhSL+o8Mi2Yq/l+vT4QluXTGsAAAAABJRU5ErkJggg==
!usage
{{{[img[icon-home-inactive.png]]}}}
[img[icon-home-inactive.png]]
!notes
Home iconOpenCliparthttp://openclipart.org/detail/19535/home-by-dynnamittPublic Domain / CC0
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADHAAAAxwBS6gt3QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALKSURBVDiNrdJfSFpRHAfw3+1eu5esS01HBK0JYvkgVBAs5SJ7SMLE6UOyDVYPe9iEvfgQQq9u7mFsLysYYybluOIQ2m0u4jpFkiaxlzH2coU9SMWdMdRqrtS0s5fJzPWffeHAOb/zOx84hwMIIThpKBQKcn5+foZl2VmFQkGe1v93AtAcCoWisVgs7PF4JhBCYLFY2qLR6DtRFJEoimhxcfH9yMjIpbOCrYIgIFEU0cLCwjOHw3ElkUh8FEURcRw3x3HcnCiKaHl5OWG3268eB2J/MMAwrFUQhFw6nY6Ew2HX6OjoS7lcrl5ZWXlaKBRCAAAURZkZhplIp9NJjuNuud3uL1CXQ6DP55tdX19/YbFYZpqami7H43EnjuMbg4ODXgCA1dXVu5VKpVOv1z/J5/M/lpaWxpxOZ6wWbKiZ/9za2vLbbLY3EomEjkQi4xRFlRmG8UulUloqldIMw/gpiipHIpFxkiRpq9X6dnp62nYk6PV675vNZl+xWNzled4qk8l6dTrdFEmSjdUekiQbdTrdlEwm6+V53loqlXZNJtNrj8fz4BDo9/sfDg0NTWWz2VQwGDQrlcoxrVY7SRAEVv9GBEFgWq12UqlUjgWDQXMul0sNDw8/Z1n2EQAArtFoXun1esfa2tonlmXvGI3GxxqNxlYP1aejo6OvpaWlMxAI3Ovq6hro7++/zfN8J24yma7t7e39crvdN+12e6C7u/v6aVg1crlc1d7ePuByuW6oVCpNNpv9hiGEAMMwAgCaBUHI0TR9Vg8AAHZ2dkCtVrcBQB4hVG4AAEAIlc+lHJGq0XBa43nz30HipM39/f1KMpn8gON4GQCgUqkQPT09BolEgl8ITKVSXw0Gg7G2Fo/HP6tUqr7jzpx4ZQz7518fWTszeJHUXrm4ubn5vVAoyKqFTCZzUH8gk8kc0DRdqq63t7czAFCsrn8Dg8yF7ag8tfsAAAAASUVORK5CYII=
!usage
{{{[img[icon-home.png]]}}}
[img[icon-home.png]]
!notes
Home icon
OpenClipart
http://openclipart.org/detail/19535/home-by-dynnamitt
Public Domain / CC0
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAADHAAAAxwBS6gt3QAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEwSURBVDiNzdS9SkNBEAXgL/6A1oKViDaKbbCMlWBqrcTGvEAaW/MC1kLyCnaSTrEXUoitZTqrYJEihT9r4Vy8anK9KQQHTjGz5xyGnd2ppJQURaVSmcF5pM2U0luhIKUkTOdxFTiK2iIukQKXWMw045A3XMgJT7CE28jPAilqS9MYXmADD3hFE9VAM2oPWC9jeI5tPGKEA9QxDNSjNgpOdaJhmGbiAWo4xnPuKp6jVgvOEPVJHTZC0McWTnNG33EanH5oGl8M0QriPVbQKTDL0AnufeSt7Am2o3CDZXRLmGXohuYm8vYsVvGEQ1xjV/nYxA72sIa7Se9wWixkPjNTdFMq/r/h3C/nbz4WwkuOv1/YyC9D6f34WvTG8EoPZdyyLFygfzqUFx8fftoY+Lxj75ajH1DUj/UaAAAAAElFTkSuQmCC
!usage
{{{[img[icon-idea.png]]}}}
[img[icon-idea.png]]
!notes
Icon for "did you know"
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-logout.png]]}}}
[img[icon-logout.png]]
!notes
Logout icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALHSURBVDiNpZVNa1NREIafc5N+aBV720uLaEBpEXFhyUJoaXUhuhEEtepSDfQHdFOkbqyItOBfSBdd6Mb0A1y5U+sibkwVYxUqFU1bEkhaE7Te6J1xYVLvbaqiDryLmTMz5z1zhhmjqtwwpnM7xAW6DIT4C1HwLHj+GQauqy6YEehsgmQ/tOwH8zfJqrIIOgmFT9AdOgVT/XBwHxj9cWMt2tvRhgZ0fX3L82Ywu2HbAnSFBboiYLzfMJDJSV6vr7P75EnsX/hEwAh0WUDIAzaDs2eR5mY8oLx3L42RCI8Az7LQvr4a/wqhkAUgmxAaHqZuaorR7m7EzxQwp09TPzvLo5GRmjgAxqBYBK3i86VLKiKaSqV0YMcOLYJ+XFzU+fl5vQtaamrShVRKRUTvX7mi/tgxKDIGxTXQKj5lMprJZPTEnj26VLGtvn2r6XRa71T095GIZpeXNZvN6gNf7BgULXw10I4O6traSCQS3FxaorFiF1VUFanoTR8+UEoksG2bZwcO+GuIpf6i9vYiIrx88oQOn720vMzKyspGQg/YNTuLiOD19PwkBISrxQb4Fg4jIrSXy4HP+HLhAvdUuerzDbsuIkIuFAr4Bp7szc0hIrRGo4F22JnNcj2X2yiBBxCNIiKszs0Fn+xvm6/pNKV8nnOxGAuOU9MWVajjYGIx8vk829LpQNsEGbou7wYHsW2bcjyO6zg1zSuOQ108Tti2GRoc5KLrBhiG8SkAbdPTPD16lCOxGGvJJIWJCZxUCgNY0Sjhy5epb21lfHyczulp9m+KN6NQPA87fTY84PGZMxy/fRu7pcV/RKFQ4NrQEJ0zM8QIjqcElMwtWO2HZraQN/X1JA8dwjp8mAKw9uIFja9ecb5cpmML/0lYM6PwsBuOtf3jLKxKDjQJjy0XBpJQyIH+ch7+AZVkBRcGTHUFNPznCnArK+A7dFOY8d5pSVMAAAAASUVORK5CYII=
!usage
{{{[img[icon-mathpanel.png]]}}}
[img[icon-mathpanel.png]]
!notes
Icon for mathpanel
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANUSURBVDiNpZVNbBtFFMd/s7u2l2xcO07SfLQNUAIqDWAhICAITVGKckDqAaniUOBQRYILnBBwpEKCFNpDJSQklEu5gQOhAkElKqgCh/SDkrakCbRUNHbBTXBiu/HXencfB8eu4x4g4klPK81ofvP/v5mdp0QEFbvY2xLQxhxPojpKZx3hIq6hqXPLJW9E9my/rPh0pjfi16cOPrQ50t9qKbUeGiDAqVROXvspsbRku4+plqOzJ957cMuO/lZrvaw1cSqVk9d/jk8ajivRaMRSttTZ+OU8fPsNer7w7wp1De+JQaJPDirHlaihKaU7VZgI6uA73Dn2IR1/L/5ndWeHzlAaGERTSjcEKK8C9UOj3H1olOQjjxIffgbPNLEmYmSHhtE3bADA+mKc7M5d6OEwAJ7PT+m5vSip1NOgCrwwTejIGDMHDuO9sK+yww/fY3z9JfnDH4HPhxTy8HmMlbdG0Tq7GrxXPjWg/939pF5+Ffv5fbXJpolxnO33UTZ8lbHps2iGjruxE8eTSok0bQ3XEMAWsI+Mg67XYIjQfnqK5aeepnpg/tMnoaMLG4XnONjFApphYPj8KKUaLGt1MEA/fozgrxeJ7z+AW1Ucn6fU1s71RJzUtXlMqxnPdfH5AwQ3dtxUWK4DVSN4NEZm02aKj++sbaQlrpIvliiUSoQ23Y7PNNF1g/yNDMpvNiisC5VJE578jmxfFFtpeLaNnc/TeeUyjtVMsVTiRnoZn3kboc5ugt09qNV/TKsC67Ppg/dpS8yT6XuAXD5P8o8reOUyZipF07U42YUkzd09hHq24gtFcFA1UZo0wMquR+j4MbIBk8Xh3eA30a0gV3+bpWjotC4kuWNxEX9LG5hNa9aKrCq05WYGPvmY9plp/tray59WEFuEQHsX4Xv6KIRawPMInZnC0fQ166o34RbL1skfEaW4PjDESibNha8+I72QRAw/K9GHcQHPtm8pU9Wy4SGuLVB9ahKvvMly/wCpZ/cSLhWJ3BtFD5gopZh/422y2+4n9eJLSMNBCuAhrrImZk/s2bZlx12h//d8/Z7JSWwuPqnlyt5IbC6xdCmdE0fAXWc6ApfSOYnNJZZyZW9EVVuA5dPGHJGots4W4CGuodS5XLnSAv4BrjK83Z2DBXwAAAAASUVORK5CYII=
!usage
{{{[img[icon-multichoicequiz.png]]}}}
[img[icon-multichoicequiz.png]]
!notes
icon for quiz button
multichoice
!type
image/png
!file
!url
!name
icon-multichoice.png
!author
Pesasa
!source
e-math
!license
pd
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACPAAAAjwBfjVtygAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGGSURBVCiRlZMxS8NQEMf/r8l7TQo2YGsgUSFDFoNFCFIoiNBNcCkd8w0KncShk34B6dylax1cOvRbWKRFkqGttNQhKC5Sg/Q9KU4VJGDsTXfc/bjfDUeazaYqhLiklHqMsS0kBOd8IYToUEpvZCHEpeu616ZpSkngOqbT6ZXv+5AppZ5lWVI2m8VbGELf3UU+n/8TXi6X8mg08uS16kevB6dex6zdxkMuhyAIYlA6nUatVgMAMMa25HUjMgx8VquIdB0npRKKxWIMJoT8qn/gw7MzhEdHcAwDhBBkMpnE21Pr5NG/x9PrLfzgIRGKbY7EGC/8Dqpkodt9xmAwiA0rioJGoxGH9/KnUN/3oW/bOC6YqFQq/9dWVRVpaQeKomyu/d7r4eDiArNWC4FpYjKZxIYZY/A8Lw5/5nLg5TIiTUOhUIBt23HNVOpXLXPOFwDgnJ8jdF04pglCCDRN+1OZc76QhRCd+Xx+vVqtJAAYj8eJt4Zh+CWE6MiU0pt+v4/hcLjxV30Dvt6F8UhMZdkAAAAASUVORK5CYII=
!usage
{{{[img[icon-offline.png]]}}}
[img[icon-offline.png]]
!notes
Icon: offline
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALaSURBVDiNnZVLaNNZFMZ/95/Epk1NamqiMpq6CBQs2ir4mIW6UaTgKD5WEV0JLpzFDBRE7U505QMRREERZzEKFnzhY2GhzmYGZwSjJvFRNVGnD5Iak77SpPeeWbSNliYj8cIP7uI73/3OuVyuEhGiSgUtn++CFArNymazUcESrbVyOMImmdy7RKSbCARf+P2poc5OI8ZIpavvwAGJOJ0Sc7uzEQgS8/m6hjofGBEtldLffliegzwH6f15v4n5fF1E6zxp0WMiJl8RyaNHimaJLZvFjA1LtM6TJub1ZkXnpBJSp44XzeIbN4gZyYjonMS83qx9YrS65MDzOsf9+GXux38j4G5kW3A//o4wfb+2AeBav5ZF16+iquxFjwlDMSUNb705z/lnhwB4/fkJY1dus/NMDoDq1SsJ3LyG5ayaVv+/Ce/GLxX3zX/B9jMjYMDZsoyGOx1Ytc4ZtRYIiC5J0LMUgKbHsOc0WAZobGDxvQ5sntqZNchUwtIthxp/wTz8h59OvsemYSTgZvmDu9jmzilbMznD0i37w2l2HEliCjC6wEVLVxf2efVl9ZMtTyWczujfj0ls3YUZGSXjhd+P+XAsnF9S+4UyCXNPoyQ2hzCDQ5j62ZxtH6TfFWdgtId657yy6SYTysS1TzIWe0WiNYROZ7B563h6dhP9P0yIIwOPpmlngEy1rAFN/u074q0hxlMDWO5aGm5f5pm/r3j622y0qC3N1AzFUHj/kfimEOO9/ViuahpuXKR6RRPdmUjR8F32xTcSgl200eO9vcRbd1P40INyVhHoOEfNjy2kcj1k8umvDF9S7hEggmijLeVwhP/dd5D8mwRqloPAldO41q8E0bhsNTTXr8Ku7FTba1jtX1f2EQw//FOUwxFWEQgqV80TyzPbteDEIdxbN8w4XIvGUhYKVTLZ8B+P5OOetk86+WmNKn4Bc+dckML4d34B9rBJpfcuEen+DwWmV2LsaF1VAAAAAElFTkSuQmCC
!usage
{{{[img[icon-online-check.png]]}}}
[img[icon-online-check.png]]
!notes
Icon: online-check
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIhSURBVDiNpVVBaxNBGH0zu6s1NpUmbDwIQcti6EEXLFQvFbwYvQhCiuBRehPBgyc968kf0EJB2osQvcSDREiheqkWJC6lYmlqg2BlNWmbpGC725nPQ5I2kp2F0A/eYZjHm/fN+4ZhRIQbr5gVPW5O+9K3OdM09FCShDC44TT2/kzkx6mEdBZWJpeoFN05KUlSryVJUtGdk5lcopLOwkImZ84X3YIkEnQUFN2CzOTMed2Xnm2bYwwkeum0q2xzjPnSs3XONI0RAaAjCTIAnGma3lwGu/PELvLlGeTLs0gOpHDbuo/U4EiocFOQZODmm7UpTC09BgCsbn/Bp1/v8PLmCvr0iFKQHzrsxtvyi//IO/423v98reS3BAkgEQjr1IUuB8l+S8kHqO1QBuJu6iHODQwDABgYbg3dw3DskpLfdEhQnng2eh6T1wo40z+E68k7eHDxmdodCYDaoSA4FACoe1Vs7KxDY1oor12tlNVDXfz9AQTCj8Yqqn83EO87HSrYCkUqUaotHZCXq4uh3I5QVGMgsFZbPhD8Xv8ayu1oWX03pQ7B9fq3UC4A6BJSEPbBwLo2K7suat5Wh+AKVM+UQJCQghvccJzKAgWNwUktAjs+Cp3pOKFHcDlxVTkyTmWBDG44LJ2FFT0W+/hk5HnMjo+yIKeCBDjjgV0QCE51kZ5+frTZ8DavsMMvYHDal/s2R49fAIQwuO409rYm8uNU+ge3GMvV9TPZRwAAAABJRU5ErkJggg==
!usage
{{{[img[icon-online.png]]}}}
[img[icon-online.png]]
!notes
Icon: online
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAQASURBVDiNlZVvaNVlFMc/z+/e33a3mraNrRDLoVdXCl3TNIVskNGUEhrMYiGBJGFUZtkL0zdSBkYKEiyxLPKNloHtrhc6cpsKMVuseWG7atw5TWe77rc/93d35733d5/n9GJ6TVeBBw48nO85hy/nfHmOEhFW/aCCJYUVBzzjhSzl83EPZkRr27IjyczQhuNrJUbtEYL14UqnO95qjBgREUnnUpLIOPJflsg4ks6lRETEiJHueKupD1c6tUcIUh+uONkdP2FEtIhoaY41yvpj1dIxEJZUdlQmvITcwia8hKSyo9IxEJb1x6qlOdaYx7rjJ0x9uOKk5ZlsKFSxQiGaQ9GddA228NkzLZy93sY7bcvpH4uAaBDNxbGzvNW6lMhQO7trfqZrsIVD0Z0gmlDFCuWZbIi6pjJXdFo6rzXLptanJHljUD489bx8F90pudy4iE7f4Z7nyqHoR7L99GoZT8fl3dbl0nmtWUSnpa6pzLUmR6tpijWyZfE+mi/u49GyJ3ml+j18SnEleZ6ve7bTduUwnpnAb/loqN7CvNInCPd9wZuhT2mKNQIahVJ+ADfjMJqO8/B9c2i78j2f17SBGE4P/MjHv76W3+jhafP58rkzKBT1wbfZdOpZGua9z2DqEm7GAaWUBXDZjRJ84HGc9AClhZUU28WA5mis8Q6JXHKj/H69FdAU28WUFlbipAeYX76Ey24UAD8ItuVDmywFlp+cyU4uAUBkqu6Ml8dzN2uyOo1t+QDBAgj4AiSyw9xvl5DIOLhZBzDUBd/ANzkVAGZPn8+iyhWAwc06jHtjlNjTGMsMEfAFEDHGQmBWyVziqT8Zz4xQN2cDB8/tAtHUzHiRr1aeoizwIE/PeIHGmhZ8KBDNwXO7eGn26yQyQwzf+ItZJXNBmGSoEFZVNdDc/w2rZzWQ8lz2dG8GDJVFD5HMjjLhufgtH2DY072ZlOdS+8jL/NT/LaurXkUxOZ5J2YhmTdU6eoY7ab96lK2L9rJyZh2IJjL0C57J0jvyG56+AaJZObOOrYv20n71KL3DnaypWpefqwUCYihQNjuW7Kcv0YuYHAvLl4EY/hiLAJDRac6PdIEYFpYvQ0yOvkQvO5bsp0DZIOb2UkADmiJ/gI0LtqGU5GN9iZ78UmKJnnxcKWHjgm0U+QP52E3ZcLP7v1tfIpp/97vn/zcXwG8wWsihUFPAidw4gxNXbzdMXsgzudsEwWC0ZVt2JOJ0yK0f5Z+ezo1T5C/OF9nKnpJzyyNOh9iWHVG1RwiWFJSd2b54d1mofKm6m+lIxuGie4EiXzHB6Y9R6AtMYRYZ7pRPuj4YSWZHlqnbJ6D0gGdyIYt7PAFobVv+SDIzuuH4Won9DVepb46u8fYjAAAAAElFTkSuQmCC
!usage
{{{[img[icon-presentation.png]]}}}
[img[icon-presentation.png]]
!notes
Icon for presentation
!type
image/png
!file
!url
!name
icon-presentation.png
!author
pesasa + OCAL
!source
emath
!license
pd
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMqSURBVDiNlZVPaFxVFMZ/5707897Mm3QyUzGkTkDiQKuCQyotdWERY0ELurBElw0SxHVps7M7UcRlIUGKFhQXxihFFHRVWhApljSiNs40gfwxUGpiInmZzJv33nExk+k8q9Ac7tnce7/vfucP94iqIlO/lQuOdTGMtWIjNnuwCI2MJbN/NeIxHXnitvD5r+Vi2v7xg6dLxaP7PZG9sAEKXF/z9eyNlfX1IDomhcu3rrw/NHD86H5PgkaD6s0bD0wmIhw8fARjDNfXfB2fWb5qwkgrlaIngcLXlz7k2KEylmU9EGEQBHzzyUe8NPomlaInYaQVY4nYobYuHHx2mHfPvEV/fz/SJrVEsI1BVdE4BhF207K4tMT5zy7TbOMtEdsodDZsN8MLJ04wevo0ixcu0Dc/j12vs9hoMDgxgTgOW1tbAGQyGSYmJyHtdvAKWLQJmwqhguM4bFSrVDY26IsilvsG+SNb5tq584gIjUaDIAgIwxDXcTvYjspuwqZCOp1mX6nE7MwMdzIBt19e5ofSU+wMlrFtG9d1yWazeJ6H67qE/ItQgUBb3mwrzBaL2OPjTP+5yu+f/sSTZpFTb5/BcRx6e3spFArkcjkc1+lgA22FbOjKYdhWuL29zcNDQ7w2OY20O3NzcxMRIZ1Ok8lkEJFOyKL3Kp8oSlOhx3HY2dmhXq8jIgkH8DyPfD6PiOC4ToLwPxWmUimy2SzGmE7zigi5XK6jbJc87Tj3K+wmjG1DrVZrA2R3YUwK1ZgoihKNvTA/zyPDVgffCrmrQj0HBth+/hS/BEECuPTFxwSqlEfeSOynTw6hKedeH2pbYdD1QqH8eALkr91ldaGGnTL0lB7F3ZdPnHdj7ws5YaqsXvueO99Nc+TsOzT9v/n5vXMceHWUvsPPwP/8SyZGo0BbuUKVaKdOVPepfjuNVG/y0MnX0aiJcTMUh19h9ctL3F1cYPC5F7GzHpaTab0PxGgk3le3rowcGjj+WN7b61eYsPlNX6fmlq9afjMem5pbWa9t+BoqRHv0UKG24evU3Mq634zHZHcEeCnrYqhasfY4AmI0MiKzfrM1Av4B/lOFCyd9lssAAAAASUVORK5CYII=
!usage
{{{[img[icon-preview.png]]}}}
[img[icon-preview.png]]
!notes
Icon for print preview
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAUogAAFKIBqj7LWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM2SURBVEiJxZdPSCpbHMc/E6bUooyijBZtzKAWCRbSokXL6FFBVO7cVQYhvBsk2G1zFwrdwNeimgoXtYwgaNUioUUUkeaiKFvF648EL5HSpoU4d3UHSzM1efcLB2bO/M7vc35zfud3ZgRZlvkTUr3vmJmZaVhZWfm3EGeCIDAwMPCPKIp/f2osy/Kb5nQ6GwG50KZSqeTR0dGf7/2+b2kRp8rtdtPY2JhTtAsLCxweHpJIJPB6vd8ARFGcKiji09NTOVeNjIzkFXlJTuHkIYvFgtlsViIfGxv7mcmu6ODKykp2d3c/hRcdvL6+TnNzM6FQCECBT0xM/Ei1y5pcmfT09EQgEODh4QGj0YjBYEAQBOW5JElIkvRmTCKR4O7u7i/ge97g+/t7bDYbOzs7pBad6upq5ubmmJqawmKxpI1zuVwcHx+nO8wlq/f392WtVqtkrFarlQ0GgywIgtI3ODgoJ5PJtGzv7++XAbmvr+80r6yOxWJYrVai0Sh6vR6fz0ckEiEUChGJRLDb7ZSUlLC1tcXi4mKuL/BzsNvt5vr6mpqaGg4ODuju7lbWVKvV4vF4mJ2dBWB6eppoNFocsM/nA8DhcFBbW5vRxul0UldXRzwez7ye+YKTySTBYBCArq6uD+1UKhXt7e0AnJycfB0sCAJqtRqAl5eXrI5+b6GysrLigE0mEwB7e3sf2sViMQKBAIAS+ZfAAL29vQDMz89zcXGR0cZutxONRtHpdMpEvwy22+10dHQgSRKdnZ0sLS1xc3PD6+srR0dH9PT04PV6ARBFkfLy8pzAORWQq6srubW19c2xl1o8ANlkMmU8LgsuIABNTU34/X4cDgcNDQ3KhNVqNS0tLQD4/X42NjZyi5Y8TieNRoPL5eL29pZwOEwwGOT5+Znz83OGh4cBsNlsXF5eFhecKp1OR1tbm7LVVldX0ev1xONxhoaG0k6nooHfq6Kigs3NTTQaDWdnZ0xOTv4/YACj0YjH4wFge3ubcDic1T7vD4FsGh8f5/HxEavVSn19feHg5eVldDpd3hNYW1tTrj9KtqxgURTzhuaqNHBpaalkNpv/KzaoqqrqPPVe+FM/bb8Aph8ne/GcoUcAAAAASUVORK5CYII=
!usage
{{{[img[icon-print.png]]}}}
[img[icon-print.png]]
!notes
Icon for printing
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAUogAAFKIBqj7LWwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIdSURBVEiJ5ZfPqxJRFMc/pzQGJ8nFK5QhdPdEEmshRtYqiJZCQS4NN21TWsWD2iRhf4C8oHWr+htq0+ZBuYkWBsLbhBSVSWj+OC1S0ZrR8cfTRV84cJl75nzmnDN35l5RVbahY1uhAh6nCRHxAueB40vG7gNVVf21EDgcDr8oFAqXDMNw9JmlTqfTL5fLB8A1WwdVtbV0Ov1OV1QqlXrvFH9uNr1ej1ar5TpTr9eLaZpz/eaCa7UalUrFNTgej5PP51cHDwYD2u22a3C323XlNxfs8XgIBAKuwW7K7ApsmibRaNR2LhQKkUgkpq4ZhrEe8CwZhkEwGFzq3rlgy7LI5XJLBV8JXK1WKZVKrgMmk0mKxeJiYBE5DdwGfLFY7CTM7rGdLMsaj5vNpk9EHgA/gaeq+vUfsIj4gUfAPvDDNM0b8OcFymazrsF+v3889vl8HeA5EACeiUhOVb9PgYE9YE9VPwFEIpF2JpP56Jpoo0aj0VHVD8PE7gGPgTtjsIicApojKEC9Xk+uAv1bqloTkS8iclZVD0cZ7wI3ReTcOmE22gVeAYcMdyAXAR3aQ+AMcMLpz7KIATvA24n411XVdgfyEngC3F1Hiqr6eZjllOzW8S3gPvBNRNx9/2ZrB7hq90QwXeqjNsdSb0RbB/c3yOwB4x4L8Jqj7+8B4FFVJtfb5Q2Ar4x4MnmEEZEUcGHFUjqpqqpvxqz/7uz0G1pHidGzQdX4AAAAAElFTkSuQmCC
!usage
{{{[img[icon-publish.png]]}}}
[img[icon-publish.png]]
!notes
Publish to students icon
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon-sethome.png]]}}}
[img[icon-sethome.png]]
!notes
Set home assignments icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALZSURBVDiNlZVLSJRRFMd/9/tmdGbUBsbQ6Amp2CIQe5i1MLNFGr2soMHyUbmIpAcE0cagRQwUBmEGlYqL0NoUraKgB7XQIIuoTfRQZmHlY8LRfMw333daTH3N2Ah64G7u+Z8f955z7rlKROCNykXztiLRAkTTmY8py0Q53mGN1rNGPivpJRdtQQ9Zp3y4VytQ8+KBwOQHYfBqCCtcrOSt9zlZDSW4Vs9KMk0LAF3XZudOfRAGW144EKOA1DyFRAAYDU/SFxxioS+dpYt9TExG8NdfB+BO63E87pTkwNQ8hRgFGqLpSBTEADF49vI9haXnuXjlAcMjPynbE6A/OER/cIiyPQGGR37a2sQVBdF0DSTRgUl+bjZVe9eyqSJAmieFG01V3GiqIs2TwqaKAF/7vyWHIsSSEreZn5NJS2Af+4/coqhwOWcbtlB+oJkK/zXOnSijqHA5Gysu8/rtlyRA/gf2BwfZXdvKYf86tpXmsbP6FuGxKUbDk+w4eJPtW/M57F9HaWUzD5+8Twa0QCIgEdo7u6ms6+BSYzneDCe1J+9gGKad94hhcqihk4U+F5cay6ms66C9s9uOj7F63WEZuCCPumrE43bKvTa/HKtZL7EGm32dPFos99v84nE75VFXjcjABZFed1hJrzvMojMZIvDxywif+kLsqrs7e7/F2eOuKpYt9pKfk4lSwPemMbvKCoNVOQswo8acYACmGYtR/Kuywy6KbdE5AxFzRixJgGImCDLSU/B5UwEIjU4zNh6J00aTAYW/z84WxVn75c3s374SgNv3P1F9+ukMYFzsXK7s0C3b79AtEi3pCS0zftOpS2JMfJ5mpMOpywygZSp543pO+sYSHNkKwLKE4MCELcnKdOFxx2bur4koQ6Fp27diSVqsXQCiP4Tx7hexAYurh/QNPhxZ852uf2CDwvirEEwVK/sLUKmtiFWAqHl+AWKitHfIdD1r5PNvdjKBFBnnJvUAAAAASUVORK5CYII=
!usage
{{{[img[icon-settings.png]]}}}
[img[icon-settings.png]]
!notes
Settings icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAPiSURBVDiNlZVPbFRVFMZ/9707c9+bKdNp6R9KWx2grQ0qjQWUECXBEIO4MZIgOzESF65MXLgEEzUmrty5wEQTExcGFxpX1QWopAmBMMWYFgYQof/b6R9mpu+9efdeF9M+Al1xk5eb8/J9533nfOfdK6y1iL2f9EmVOWeMGRKOcHmCZY3VjuMU47B22l45UxIMn+1zVXa0Z/h4a7Zth3icIDD0yttYHCbjAgZnU9Lqwh17/+r5sg6rB1y3cOyn7heOD2a2FoS1lsefDmeST1+b48hAyJ83DRWzZRMm5eeF39zlV+ZLQ441Zkjle4XWGq01XfI+/WqCjXhHZoa2tq10dnbS7S8m71/M/0OnnE5ile8V1pghicA1RgPQlZ7hg+F7bM2l+PXaX7hS8sqgwvM8lFK8c1Cyc2KM1ozm7cMFrpdm+XwkZjLq3OiPKwG0NgDU6ilcF1pyHu8fbUUphZQySXhoXx8vDxviOCaOY7CW5chL+ECjw8ZojNEsRDl+GRNks1mUUiilyGQy+L6P67rU63WiKKJer1Or1fjm4hrL9UzCB5BYHvlCS7aRMJVKoZQi1obfL9/GQbB3sB3pOsRxjJSS3uaYSwsPuViQAJiIp71pdrVUOLKnKVGnteHDr6/z2/RuAI5s+5svTvVjjCEMQ47u8fFTY/y7ABfn+hsKLZan1CTnTina2vpJp9Ok02kALo3dZWRyAENDxcjUICcmphjozhIEAXlfc+z5RivGf57lPnZdoTUsP4hobxd4nkccx2itSTtgTYy2DZgQMVhNrVYjCAK01swtrjK7FGJtbr2HwPjqNk5+W6W/ucRHr/scHCoQxzG7d7ZzYtc1fiwNAPBWYZxCRw8rKysEQcCNqZAvR3eyEm/BIh4m1NqwrH0uz/cwUrzDS8/pZDQ+Pvksb5Rm0NrQ07adcrlMGIZYaynesyyGTQ03sA9d3rAcYGZZEwQBxhiiKCIIAjpyDkEQUS5XCYKAMAzxPI+unHmEi12fw+S385Z479U8WmvCMEzmrVqtJrvruigvg5SSw3uaOdo9nvDXXQZjGi56TkRtTTB+Z5bvLyygXM2+gsPAdp8gCFioOly4GnBlpoV396/SnrMU51sTvgUE+z9bkn3H8xuq+3Jl6kZwt9ICQI+/yFdvLpHNeHz3xxo/3FifN6Hp9CtM1pqTiuPS+WWJcIq6Mn0Iv0MATCxtABolTNWaKFfmyW1xubWYSkrTwH8PmhIca3MW4RQFw2f7kGqUjgOt+O2bDliAZ5rncYTl1morkZGbAWvzlrnRMnF4QGxcAbjqHJghxJNdAVirwSmiw9P2ypnS/ydXGW+hcsGAAAAAAElFTkSuQmCC
!usage
{{{[img[icon-student.png]]}}}
[img[icon-student.png]]
!notes
Student icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANaSURBVDiNlZVLbFRVGMd/5947U9oZ+pgRC9qaVkYb0DIh2LE+SkJJTBQXJuoCQ2JidOPaGF0aNsRHws4FbESNBiFAVMJCTB2jwkAlZWhrHQxMH6nT6cwwjzu3c1/HxTjQ4Q4LvuQsTr7//3/O+f4n3yeklIjvZiI9bcpR25VRFaFyH+EgHU0RU4Wa+7Z8fft1wfHpSMivXvh0V18oFg4I0YolJbTOIIFETpfvTS7m86YzKnrOzE58vLN/dywc8DDyf37Dv+cPYeZvsuHBITr6n+KhFw+iBcIe4UROl+9fWYhrtiOj0VBAmLIZUPknTvrbt27vjeUkxnKSUupnBt75EX94axM+GgoI25FRRRFCtSVY65frMn/6A9x1h+x8+hUCwRBWIc3yDx824yXYEhQhVEWCJ1lamqE8fxXbqVdh8LEYO55/g337P6Kz6wEqM99TzV738CSg0EpwcYYNPj+dXZsZfHQXsfE3oa2b9q4tPLFjvF6S1E8eHoDWEFwf+vwk24fHeGZ0DNuRdRP8G8Gp0bOpHwAzd8PDA9AkcLch5fQ0WX8RhIrmEyBdcEyQLuZaBQC7mvfw5N03dM01MuePkJ1NEOzrBUWtCzk1MItgGxh6qY6t5u99Q0uCa9VYOH2Y/K/HUKXCymqOqlGjwy/A0m+L66UsSHAtwyPYZIqjtREcHqdWLmOumRTLBmfPnsKybLDKGPkFEue+IDkZr5OHXmppSpPL7Y/H2HLgEJYjsBxBrlBBIKlVK2juGrGxF1ADnbiqD3t4f2uXpWx2WQ6MUB7YR+lmCr3Qjebzofl8ENpGMjHBmb+3EnxkgO7f/mBzdISNm3rvcOX/pjTc+v3zT1j+5RwKEmintFShUq0R7GiD/CyX5jJkSoLMtTRc+wxHCJ488C7bXn7tjimNJ189+RXJE8fqx6yLi9ML7B2JABC/kiabzTXl44cPonaHGXxuT13QRTqmhMsnviS7suL5Bqn5VfaORFhaKTJxKYVhOh7Mxa+P8PCze3DrvVFMzd3Sd/vCvaJUNTzgv9KrVIwapyamydyqePIIgSVU5goVqQgxJTg+HQn41AuvDvWFBrtaNdhGCe7dYG8UdXlybjGvW86oaIyAgE85aksZVe5zBLhIRxNiSrfqI+A/DeXYYNXpyVkAAAAASUVORK5CYII=
!usage
{{{[img[icon-trash-red.png]]}}}
[img[icon-trash-red.png]]
!notes
Icon for trash
red
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAARMgAAETIBkuq6TgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAILSURBVEiJvZbBahRBEIa/v7pnAiaSgKBBDOjBg4IePHrSJ/DixQfwGEHyCIIPoGdPHgSJzyAeREWCIEE8GMzG5JKDu6shSzabLg+zo0G2k3U3sWCgZ6q7vvqrupuRu3PcZsdOGBeyXZbXdsvyKRMTD44WIlkrxls/i+KVYElwEen9gWvcfahnE6Y2zOY3Q/jyPcbejxgXt2O8PszaeFjiK9Kcmc0Hs7sRAtITi/HRyU7n69Dqc/SPcGUZnn2WdlekxqrZwgpMD6t8KCWCS8BtlxaV0gsz65Uh3NyMkRIIQAiBif4Y9wbd7oeBsXLnZFmaE6xFiQKIEhEopN/j/T7cH9Pt3hsUK7u7DJoADu9cergvq/u41/1oSrpTOdQ8INZgu+y+BfQkNZTSm/r7Xghvkdb6r99CCK9HhgAImrhPJdjKTGl39/amAUipNRLEq5JNWg7i3rKUZqqMRlRCBZnKQqS23GslY0Eme/lytQihUmI2HiRmIC61U60khPHKtZqBKKU/5ep0Rmu8+kpuuPeAnb/9LrUwmwF2qbb8v0OoIOWSVDBAjerGS1kVh0JS/9SfgslBEEuplWAG92w/DoXQh3QzkCS1JU0DoyupIQGuAicAQkrngdMAbnYG9wv1vJxlb2GAT9JsMFso4GyU5qL7uUKajdJWgPUC1ktpI0gv2dl5PhLkqOy//BL9ApQKMehxI3HwAAAAAElFTkSuQmCC
!usage
{{{[img[icon-update.png]]}}}
[img[icon-update.png]]
!notes
Update icon
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAC+wAAAvsB9mMCTwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAODSURBVDiNlZXLT9xVFMc/9/5+v5kf8xugM9CRlkcLDK+Z4DRpiiYmGFOXjXGhLkx8JWzd+Re4cNWl7qrGnSI+4mvjxrYhMTU1oVrAdqC0QiFamQLzg3nde1wA05nqhntzN/fc7znfc74n9ygR4ZV5lY7rxCUjtZxSjsMRlogxjnLnirYwNZ2RvHr5Jum4k/z5jZ6LyXQwoRTqKP4QhHx4TT5ZfWezaDafdp56O/Hl670XR4eCCXX45GgHkpFu1duSbVnYuZpzjdRy/UFOGSr1qNZavpr9goLZYccUiUqEGBEmxyYZ6E4DUDM1VtaWSfcNA9Af5JSRWs5VSjuGWt2ZMYYPvn8ffySF40SJGBdjDNsifJr/hrY5j7fOv8mHP35EZ5DgdF9/HauUdlwQDNX65czs58QzJ9ndeMhecZeYH8NrD6h4VaTNZc3f5t1v36PW4ZLSySYsCK4AjeneLaxSWNmkpT3Oa8++SipIsrA0z+zyL9zx7rJuN7CBpcN0YnW6CSuACzRFyS/O8+KFl8D16DqWBCA7miE7muGzH6a5rjzyZgntaVD2MYZwkPKjKCeTXYyfGiHiuk33u3u7rFf+4WHrNrFKjMANsFJregOyz7DWEGVwcIifrl+Fg36UaoUXnr/Ab7dvcLw1wXM6iYpqlCj6unuasP/LsKo8CkEZESFp2+lJHsNQ4cyT45xhHLEKpWBhaZGNB+uMDA02MdRyUMPDUzEVwlqI0pqt+6sMnOprshdK20glws2125Sl3GRrEKVBKbFopalIGX26hY+vfE2fn+CZ3DmibT53HhS4kr/GSuk+51NnH6thPeVqA2lF+1aEcsxyw/6Om3QIPcutX7+DkuC5Dn46gZfXDA/3/6cP9aEoNaoUw5C/7t2jK3CJ/r1Dci1KXMexnkB3lOhYO7FMJ+U/t8gm+tkpFuvYQ3GaGttIhbHRblLHO2j145zYSnFrcZktZw/xquBUEBsy0ZfmRG/qoHZOAz9wRazZd6jw4ors2UFKxTKuD9E2h3NPZBErKK1wXI0XdYm2ePiBhx93GlIWRKxxtdJza+Efk13BgAJwfAh8jwAPsYK1gjWC0qAdjdaP/stGQTbCZdFKz+mSDacur85srodLIlikYaNBuwo3qnE8jdI02fe3ZT1cksurM5slG06pwxHg6+CSlVpOKX3EEWCNVu5cyYZT0xnJ/wu068OXzcTk+AAAAABJRU5ErkJggg==
!usage
{{{[img[icon_extra.png]]}}}
[img[icon_extra.png]]
!notes
Icon for extra texts.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon_hint.png]]}}}
[img[icon_hint.png]]
!notes
Icon for hint texts.
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[icon_puzzle.png]]}}}
[img[icon_puzzle.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAD5gAAA+YBEfIelQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAVqSURBVEiJnZZpbFRVFMf/d3vvzUxnWrrSQrHVUoMVWQrIEoNFlipSoLUQRQQXMIGQgohgQQniAhJCNZYPRGSRiKmUShG0gYYghEWRsEWg0DZA6TItnY03M2/ezHt+KE0UoWk5ycm9uck5v/M/uffkEtM08ShWPWtWeYrDkSG7XC8/bhiNl222fBulNf22bj3fnXj6SFQAl1U1w0bpM5rDca4+JUVzJCeX6dHRhxtmzrR0J570VPHBnJw5vSyW1fE2WxoXghDOQYQAEQJ1Xm9jUjA4fgDnNSgri3SVp2vFDUstV88W7/U1l6jeppKTAFAtRK7i86Wb7e0k3N6OsMuFzjVGVa+2muZ3V2S5uX7atKRuK26tfTvdd5e+wbkyqF+SdcXCVdey1q4cujcmOhogCky4c713TWXHpvMTE3+vndUiSaczTTOnP2OiUzU4B5Uk+A2jPi4cfjq5stLfJfjXPYW7Xngu6jXGFUKIDLePnmh2Gk2ZGQkFlFkAIkMLUV2W7UL1BxrsifNSK7OyiuIo3diLENYJ9glh1gnR4KS0crTbvST7zBn9QWDe0dIZsTCNgYzpBGAwTYoYuzI6xmEFSBgwdQAUnAlx4WKdxjmpXTQzR5ksxKoJTU3srqLAabNF0nw+BklyskuFGUl16oz6kPVwe2NJusFdz09KXFP3H8VriqfmLluAA5IABZHR4QpAZBCiwISEG7d0MzbWQRwOB/z+wM6o3svnAEBeXl6/p1paFjsVZbMYGvfEiGO1P1n8+pGba0dFZ4/LHMuJDEEUaEGtRReezMvH23KzstOWmJbAcnrhaoTfcYH6VJhbdgVPRcJ6h0IzBJgh1NZ7zn5RMTx+/Zbg1uu1zsCxU7ePd1ZdWVl5c93p0++lLIx599nFlgOkbEht+NCoHbHpIlszfOh0LpMkBK3Xh47M2h0f3Wek4VNK+J49+38pWjBtXnICuXj8r3BNemqwacJYKgMEre2G0dpm/BZtZc3W6BzxVZU7v3RFQcWiDeVDJNCsjcum7wKAG0cNmjJcZRarMpgQudzRlyNo+CBICBGig5MQJKuSQEkYx4+eqND84bL/veOihXmfzy4QC2rqyQ8/V3k+1DSrEvfk+Iak1P4cRkSXBKeKIjHBmdnodM+NGbPhghli6+3JYqI1SkJnezlRwKkCtcVEfO8YCNpxFgrqDVRtzeD337amVuWjYePKiocBKL+wOTtK0BLJHsv8gRAEZwLURCSgQXW3GQG/Oiz4p/R++nTvQAMUrhaL6UjUSYSGIRCG87p6qfozdWr2q94zgycl9+LQ4W4L2i0JcDx0ck15a/WPlviMmZIQ4IxCcAYhGCROYUT0QFgLpG1e/bpzztJNsw1UDVISI23uK5JncJFnsz1BgBMFJCSrMkXm/iIi9RvFlvjvRKqv/+E+eOTIkfBDwS++Mm+bSBkzlwsKzhgkwSB4x14IBmpGgoQYZlSU3eL1+jaUriz8AADeLJ5UPWB++zgEFLhrrLccicpLK0btu/TQAXK/5efnx6mWzHpq62Olwca/haPvQNkW06H8XwVInIJTRNwebdi3nxSey83NjU0ZEfk4cFN8vXv7wboHJu8KDABT8vMHGTy55UBZafOUglkr0WfCp0Lca/u9AgRnYIxA9bRt3bl+/jsPTdYTMADk5eXFu+xjzlDFnso5p4IzSJyB34MaAZfH8DYsKt++7vvuQoHOkdmFaZoWMERrQgAWKrgJiYVhGB6dMs6lqARCiNy2r4dQoBsfgaqqKtUevv0F8Te5pbvX9lraT449tKNYZq5LX/qDOrSgljp2fmlaT8E9/gh02uTJkx/T5eTZNjPyTUXFNndP4/8BJ7dOatZH+MgAAAAASUVORK5CYII=
//{{{
if (config.options.txtUserName.toLowerCase().substr(0,6) == 'pesasa' ||
config.options.txtUserName.toLowerCase().substr(0,6) == 'pekasa' ||
config.options.txtUserName.toLowerCase().substr(0,6) == 'rolind' ||
config.options.txtUserName.toLowerCase().substr(0,6) == 'backrj' ||
config.options.txtUserName.toLowerCase().substr(0,5) == 'ralph' ||
config.options.txtUserName.toLowerCase().substr(0,8) == 'joheriks' ||
config.options.txtUserName.toLowerCase().substr(0,6) == 'viorel'||
config.options.txtUserName.toLowerCase().substr(0,5) == 'teemu'){
jQuery('body').addClass('adminmode');
}
//}}}
//{{{
// jQuery.shuffle() -function
// Shuffle selected elements.
(function(d){d.fn.shuffle=function(c){c=[];return this.each(function(){c.push(d(this).clone(true))}).each(function(a,b){d(b).replaceWith(c[a=Math.floor(Math.random()*c.length)]);c.splice(a,1)})};d.shuffle=function(a){return d(a).shuffle()}})(jQuery);
// jQuery.findTiddler() -function
// Find elements closest parent's tiddler attribute.
(function(d){d.fn.findTiddler=function(){
return this.parents('[tiddler]').eq(0).attr('tiddler');
}})(jQuery);
// jQuery.pageTiddler() -function
// Find page content tiddler
(function(){jQuery.pageTiddler=function(){
return jQuery('#pageOne').children('[tiddler]').eq(0).attr('tiddler');
}})(jQuery);
//}}}
<<showDictData>>
<data>{"langs":["en","fi","sv","et"],"ebdict":{"invalid course":{"fi":"Väärä kurssitunnus","en":"Incorrect courseid.","sv":"Fel kurs-id","et":"Vale kuruse tunnus"},"invalid courseBook":{"fi":"Väärä kurssikirja","en":"Incorrect coursebook","sv":"Fel kursbok","et":"Vale kursuse raamat"},"correct coursebook":{"fi":"Oikea kurssikirja on","en":"Correct book is","sv":"den korrecta kursboken är","et":"Õige kursuse raamat on"}},"dictname":"course"}</data>
<data>{"ebdict":{"course students":{"fi":"Kurssin oppilaat","sv":"Elever på kursen","en":"Course students","et":"Kursusel osalejad"},"student textarea info":{"fi":"Voit listata tekstikenttään kurssiin lisättävät opiskelijat allekkain muodossa etunimi;sukunimi;sähköposti (esim. tero;testisukunimi;tertes@testi.fi)","sv":"I textfältet kan du radvis lista de elever som ska registreras på kursen. Använd följande format för vardera elev: förnamn;efternamn;e-post (t.ex. anders;andersson;andersandersson@exempel.se","en":"You can list the students one per row in following format: firstname;lastname;email (ie. john;doe;johndoe@example.com)","et":"Kursusel osalejatest saab teha nimekirja paigutades iga õpilase omaette reale järgmiselt: eesnimi;perekonnanimi;e-mail (nt matias;maru;matias.maru@naide.ee)"},"add course students":{"fi":"Lisää oppilaita kurssiin","sv":"Lägg till elever till kursen","en":"Add students to this course","et":"Lisa kursusele õpilasi"},"add course students from textarea":{"fi":"Lisää oppilaita kurssiin tekstikentästä","sv":"Lägg till elever till kursen från textfältet","en":"Add students to this course from textarea","et":"Lisa kursusele õpilasi tekstirealt"},"student":{"fi":"oppilas","sv":"elev","en":"student","et":"õpilane"},"fname":{"fi":"etunimi","sv":"förnamn","en":"first name","et":"eesnimi"},"lname":{"fi":"sukunimi","sv":"efternamn","en":"last name","et":"perekonnanimi"},"userid":{"fi":"tunnus","sv":"användarnamn","en":"userid","et":"kasutajatunnus"},"email":{"fi":"sähköposti","sv":"e-post","en":"email","et":"e-post"},"gender":{"fi":"sukupuoli","sv":"kön","en":"gender","et":"sugu"},"course":{"fi":"kurssi","sv":"kurs","en":"course","et":"kursus"},"add":{"fi":"Lisää","sv":"Lägg till","en":"Add","et":"Lisa"},"send":{"fi":"Lähetä","sv":"Skicka","en":"Send","et":"Saada"},"save":{"fi":"Tallenna","sv":"Spara","en":"Save","et":"Salvesta"},"save to server":{"fi":"siirrä palvelimelle","sv":"skicka till servern","en":"save to server","et":"salvesta serverisse"},"update from server":{"fi":"päivitä palvelimelta","sv":"uppdatera från servern","en":"update from server","et":"uuenda serverist"},"return students from server":{"fi":"Palauta palvelimelta","sv":"Återställ från servern","en":"Restore from backups","et":"Taasta varukoopiast"},"delete":{"fi":"Poista","sv":"Radera","en":"Delete","et":"Kustuta"},"print":{"fi":"Tulosta","sv":"Skriv ut","en":"Print","et":"Prindi"},"choose":{"fi":"Valitse","sv":"Välj","en":"Choose","et":"Vali"},"boy":{"fi":"poika","sv":"pojke","en":"boy","et":"poiss"},"girl":{"fi":"tyttö","sv":"flicka","en":"girl","et":"tüdruk"},"empty lname":{"fi":"Sukunimi ei saa olla tyhjä!","sv":"Efternamn får inte vara tomt","en":"Lastname cannot be empty!","et":"Perekonnanimi ei tohi olla tühi!"},"empty fname":{"fi":"Etunimi ei saa olla tyhjä!","sv":"Förnamn får inte vara tomt","en":"First name cannot be empty!","et":"Eesnimi ei tohi olla tühi!"},"invalid email":{"fi":"Sähköpostiosoite ei ole oikeassa muodossa!","sv":"E-post adressen är felaktig","en":"Invalid email adress!","et":"Vigane e-posti aadress"},"empty lname and row":{"fi":"Sukunimi ei saa olla tyhjä rivillä ","sv":"Efternamnet får inte vara tomt på raden","en":"Lastname cannot be empty on row ","et":"Perekonnanimi ei tohi olla reas tühi"},"empty fname and row":{"fi":"Etunimi ei saa olla tyhjä rivillä ","sv":"Förnamnet får inte vara tomt på raden","en":"Firstname cannot be empty on row ","et":"Eesnimi ei tohi olla reas tühi"},"invalid email and row":{"fi":"Sähköpostiosoite ei ole oikeassa muodossa rivillä ","sv":"E-post adressen är felaktig på raden","en":"Invalid email adress on row ","et":"E-posti aadress on real vigane"},"invalid text format on row":{"fi":"Teksti ei ole oikeassa muodossa rivillä ","sv":"Texten är felaktig på raden","en":"Invalid text format on row ","et":"Tekst on reas vigane"},"cannot save students":{"fi":"Etunimet ja sukunimet eivät saa olla tyhjiä ja jokaisen sähköpostiosoitteen pitää olla joko tyhjä tai oikeassa muodossa. Oppilaita ei voitu tallentaa.","sv":"Förnamn och efternamn får inte vara tomma och varje e-post adress måste vara antingen tom eller skriven i rätt format. Eleverna kunde inte sparas.","en":"Firstnames and lastnames cannot be empty and the emails have to be either empty or be valid. The students could not be saved.","et":"Eesnimed ja perekonnanimed ei tohi olla tühjad ning e-postid peavad olema tühjad või kehtivad. Osalejaid ei saanud salvestada."},"cannot save textarea":{"fi":"Tekstitkenttä sisältää virheitä ja siksi siinä olevia oppilaita ei voitu tallentaa. Poista virheet ja tallenna uudelleen!","sv":"Textfältet innehåller fel och därför kunde eleverna inte sparas. Korrigera felen och spara på nytt!","en":"There are errors in the textarea and the students could not be saved. Fix the errors and save again!","et":"Tekstiread on vigased ning seeõttu ei saanud osalejaid salvestada. Paranda vead ning salvesta uuesti!"},"delete student":{"fi":"Haluatko varmasti poistaa tämän oppilaan oppilaslistasta?","sv":"Är du säker på att du vill radera denna elev från listan?","en":"Delete this student from course student list?","et":"Oled kindel, et soovid selle õpilase osalejate nimekirjast kustutada?"},"editable tooltip":{"fi":"klikkaamalla tähän pääset muokkaustilaan...","sv":"klicka här för att redigera...","en":"click here to edit...","et":"vajuta muutmiseks siia..."},"input empty":{"fi":"Tekstilaatikko ei saa olla tyhjä!","sv":"Textfältet får inte vara tomt!","en":"Input box cannot be empty!","et":"Tekstiväli ei tohi olla tühi!"},"students textarea hint":{"fi":"joona;lehtinen;jole@esimerkki.fi saara;laaksonen;sala@esimerkki.fi heikki;heikkinen;hehheh@esimerkki.fi","sv":"anders;andersson;andersandersson@exempel.se emma;exempel;emma.exempel@exempel.se håkan;håkansson;haha@exempel.se","en":"johnny;doe;johnny.doe@example.com janette;doe;janette.doe@example.com.fi earl;example;earl.example@example.com","et":"kati;karu;kati.karu@naide.ee matias;maru;matias.maru@naide.ee tiina;kask;tiina.kask@naide.ee"},"save unsuccessful get from server":{"fi":"Tallennus epäonnistui! Päivitä ensin kurssin tiedot palvelimelta ja tallenna uudelleen.","sv":"Sparandet misslyckades! Uppdatera först kursinformation från servern och spara sedan på nytt.","en":"Save unsuccessful! Update course data from server first and save again.","et":"Salvestamine ebaõnnestus! Uuenda serverist kursuse andmeid ning salvesta seejärel uuesti."},"save successful":{"fi":"Tallennus onnistui!","sv":"Sparandet lyckades!","en":"Save successful!","et":"Salvestamine õnnestus!"},"students without gender":{"fi":"Tallennus epäonnistui! Valitse sukupuoli jokaiselle oppilaalle.","sv":"Sparandet misslyckades! Välj kön för varje elev.","en":"Save unsuccessful! Choose a gender for every student","et":"Salvestamine ebaõnnestus! Vali iga õpilase sugu."},"password":{"fi":"salasana","sv":"lösenord","en":"password","et":"salasõna"},"sProcessing":{"fi":"Hetkinen...","sv":"Laddar...","en":"Processing...","et":"Üks hetk..."},"sLengthMenu":{"fi":"Näytä kerralla _MENU_ riviä","sv":"Visa _MENU_ rader","en":"Show _MENU_ entries","et":"Kuva _MENU_ kirjet"},"sZeroRecords":{"fi":"Tietoja ei löytynyt","sv":"Inga matchande resultat funna","en":"No matching records found","et":"Otsitavat vastet ei leitud."},"sInfo":{"fi":"Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )","sv":"Visar _START_ till _END_ av totalt _TOTAL_ rader","en":"Showing _START_ to _END_ of _TOTAL_ entries","et":"Kuvatakse _START_ - _END_ kirjed _TOTAL_ kirjest"},"sInfoEmpty":{"fi":"Näytetään 0 - 0 (yhteensä 0)","sv":"Visar 0 till 0 av totalt 0 rader","en":"Showing 0 to 0 of 0 entries","et":"Kuvamiseks pole ühtegi kirjet"},"sInfoFiltered":{"fi":"(suodatettu _MAX_ tuloksen joukosta)","sv":"(filtrerade från totalt _MAX_ rader)","en":"(filtered from _MAX_ total entries)","et":"(filtreeritud _MAX_ kirje seast)"},"sSearch":{"fi":"Etsi:","sv":"Sök:","en":"Search:","et":"Otsi:"},"sFirst":{"fi":"Ensimmäinen","sv":"Första","en":"First","et":"Esimene"},"sPrevious":{"fi":"Edellinen","sv":"Föregående","en":"Previous","et":"Eelmine"},"sNext":{"fi":"Seuraava","sv":"Nästa","en":"Next","et":"Järgmine"},"sLast":{"fi":"Viimeinen","sv":"Sista","en":"Last","et":"Viimane"}},"dictname":"course management"}</data>
<data>{"ebdict":{"assignmentTexture":{"fi":"Tehtävä","sv":"Uppgift","en":"Assignment","et":"Ülesanne"},"basicAssignmentText":{"fi":"Perustehtävät","sv":"Grunduppgifter","en":"Basic assignments","et":"Lähteülesanded"},"examplebox":{"fi":"Esimerkki","sv":"Exempel","en":"Example","et":"Näide"},"example":{"fi":"Esimerkki","sv":"Exempel","en":"Example","et":"Näide"},"theorybox":{"fi":"Teoria","sv":"Teori","en":"Theory","et":"Teooria"},"theory":{"fi":"Teoria","sv":"Teori","en":"Theory","et":"Teooria"},"derivation":{"fi":"päättelyketju","sv":"härledning","en":"derivation","et":"lahenduskäik"},"text":{"fi":"teksti","sv":"text","en":"text","et":"tekst"},"wikitext":{"fi":"wikiteksti","sv":"wikitext","en":"wikitext","et":"wikitekst"},"table":{"fi":"taulukko","sv":"tabell","en":"table","et":"tabel"},"funcgraph":{"fi":"kuvaaja","sv":"graf","en":"graph","et":"graafik"},"signchart":{"fi":"merkkikaavio","sv":"teckenschema","en":"signchart","et":"märkide tabel"}},"dictname":"general"}</data>
<data>{"ebdict":{"previewbook":{"fi":"Valitse kirja.","sv":"Välj en bok.","en":"Choose the book.","et":"Vali raamat."},"give a valid previewname":{"fi":"Jotain meni väärin. Yritä uudelleen.","sv":"Något gick fel. Försök igen.","en":"Something went wrong. Try again.","et":"Midagi läks valesti. Proovi uuesti."}},"dictname":"preview"}</data>
<<showDictData>>
<data>{"langs":["en","fi","sv","et"],"ebdict":{"about to update":{"fi":"Aiot päivittää kirjan.Oletko varma?","sv":"Är du säker på att du vill uppdatera boken?","en":"About to update.\nAre you sure?","et":"Kavatsed uuendada. Oled sa kindel?"},"no updates available":{"fi":"Ei päivityksiä saatavilla kirjaan: ","sv":"Inga uppdateringar till boken är tillgängliga: ","en":"No updates available for book: ","et":"Uuendusi pole saadaval raamatusse: "},"updates ready":{"fi":"Päivitykset ovat valmiit.\n%0 päivitystä tehty.","sv":"Uppdateringarna är färdiga.\n%0 uppdateringar gjordes.","en":"Updates are ready.\n%0 updates done.","et":"Uuendused on valmis.Tehtud %0 uuendust."},"system updates ready":{"fi":"Järjestelmäpäivitykset ovat valmiit.\n%0 päivitystä tehty.","sv":"Systemuppdateringarna är färdiga.\n%0 uppdateringar gjordes.","en":"System updates are ready.\n%0 updates done.","et":"Süsteemiuuendused on valmis.%0 uuendust tehtud."},"system updates done":{"fi":"Järjestelmäpäivitykset ovat valmiit. Selain latautuu uudelleen automaattisesti.","sv":"Systemuppdateringarna är färdiga. Webbläsaren kommer att uppdateras automatiskt.","en":"System updates are ready. The browser will refresh automatically.","et":"Süsteemiuuendused on valmis. Brauser uuendab lehe automaatselt."},"give feedback":{"fi":"Anna palautetta","sv":"Ge respons","en":"Give feedback","et":"Anna tagasisidet"},"Check courseupdates":{"fi":"Päivitä kurssin tiedot","sv":"Updatera kursinformationen.","en":"Update course information.","et":"Uuenda kursuse infot."},"checking contentupdates":{"fi":"Haetaan sisältöpäivityksiä.","sv":"Boken hämtar uppdateringar till innehållet.","en":"Getting content updates.","et":"Kontrollitakse sisu uuendusi."},"no internetconnection":{"fi":"Ei yhteyttä palvelimeen. Yritä myöhemmin uudelleen.","sv":"Ingen kontakt till servern. Försök igen senare.","en":"No connection to server. Try again later.","et":"Ühendus serveriga puudub. Proovi hiljem uuesti."},"contentupdates done":{"fi":"Sisältöpäivitykset valmiit.","sv":"Uppdateringarna är färdiga.","en":"Content updates are ready.","et":"Uuendused on valmis."},"comments ready":{"fi":"%0 sivukommenttia kirjoihin: %1.","sv":"%0 kommentarer till böckerna: %1.","en":"%0 page comments to books: %1.","et":"%0 kommentaari raamatutele: %1."},"username":{"fi":"Käyttäjänimi","sv":"Användarnamn","en":"Username","et":"Kasutajanimi"},"give a valid username":{"fi":"Anna kelvollinen käyttäjänimi!\nYritit nimeä: %0","sv":"Ge ett giltigt användarnamn!\nDu gav: %0","en":"Give a valid username!\nYou gave: %0","et":"Palun sisesta kehtiv kasutajanimi! Sa proovisid nime: %0"},"show userkey":{"fi":"Näytä käyttäjäavain","sv":"Visa användarnyckel","en":"Show userkey","et":"Näita kasutajavõtit"},"invalid user":{"fi":"Käyttäjätiedot väärin.","sv":"Felaktig användarinformation. ","en":"Incorrect user information.","et":"Vigased kasutaja andmed."},"connection error":{"fi":"Virhe verkkoyhteydessä.","sv":"Fel i nätverksanslutningen.","en":"Error in network connection.","et":"Viga võrguühenduses."},"give all information":{"fi":"Täytä kaikki kohdat.","sv":"Fyll i all information.","en":"Fill all information.","et":"Täida kõik andmed."},"give username":{"fi":"Anna käyttäjänimesi","sv":"Ange ditt användarnamn","en":"Give your username","et":"Sisesta oma kasutajanimi"},"courseid":{"fi":"Kurssin tunnus","sv":"Kurs ID","en":"Course id","et":"Kursuse ID"},"userkey":{"fi":"Käyttäjäavain","sv":"Användarnyckel","en":"Userkey","et":"Kasutajavõti"},"give userdata":{"fi":"Anna tietosi","sv":"Ge din information","en":"Give your information","et":"Sisesta oma andmed"},"available characters":{"fi":"Käytettävissä olevat merkit","sv":"Tillgängliga tecken","en":"Available characters","et":"Saadaolevad märgid"},"Ebook Settings":{"fi":"E-kirjan asetukset","sv":"E-bokens inställningar","en":"Ebook Settings","et":"E-raamatu seaded"},"Settings":{"fi":"Asetukset","sv":"Inställningar","en":"Settings","et":"Seaded"},"Choose the theme":{"fi":"Teema:","sv":"Tema:","en":"Theme:","et":"Teema:"},"Choose the language":{"fi":"Kieli:","sv":"Språk:","en":"Language:","et":"Keel:"},"textbooks":{"fi":"Oppikirjat","sv":"Läroböcker","en":"Textbooks","et":"Õpikud"},"byebye":{"fi":"Moi, moi!","sv":"Hejdå!","en":"Bye, bye!","et":"Kohtumiseni!"},"editsolution":{"fi":"Muokkaa","sv":"Redigera","en":"Edit","et":"Muuda"},"edit":{"fi":"Muokkaa","sv":"Redigera","en":"Edit","et":"Muuda"},"areyousure":{"fi":"Oletko varma?","sv":"Är du säker?","en":"Are you sure?","et":"Kas sa oled kindel?"},"answer":{"fi":"Vastaus: ","sv":"Svar: ","en":"Answer: ","et":"Vastus: "},"Make solution":{"fi":"Ratkaise","sv":"Lös","en":"Solve","et":"Lahenda"},"can not copy":{"fi":"Ei voida kopioida seuraavaa:","sv":"Det följande går inte att kopiera:","en":"Can not copy following:","et":"Järgnevat ei saa kopeerida:"},"not yet translated":{"fi":"Tämä osio ei ole vielä käännetty.","sv":"Denna del har inte ännu blivit översatt.","en":"This part has not yet been translated.","et":"See osa on veel tõlkimata."},"order":{"fi":"Järjestä","sv":"Ordna","en":"Order","et":"Järjesta"},"ready":{"fi":"Valmis","sv":"Färdig","en":"Ready","et":"Valmis"},"cancel":{"fi":"Peruuta","sv":"Avbryt","en":"Cancel","et":"Tühista"},"close":{"fi":"Sulje","sv":"Stäng","en":"Close","et":"Sulge"},"Close book":{"fi":"Sulje kirja","sv":"Stäng boken","en":"Close book","et":"Sulge raamat"},"Open book":{"fi":"Avaa kirja","sv":"Öppna boken","en":"Open book","et":"Ava raamat"},"Book is closed":{"fi":"Kirja on nyt suljettu","sv":"Boken har stängts","en":"Book is now closed","et":"Raamat on suletud"},"Saving and closing":{"fi":"Talletetaan ja suljetaan kirjaa.","sv":"Sparar och stänger boken.","en":"Saving and closing.","et":"Salvestatakse ja suletakse raamatut."},"publish":{"fi":"Julkaise","sv":"Publicera","en":"Publish","et":"Avalda"},"Loading book":{"fi":"Ladataan kirjaa","sv":"Boken håller på att laddas","en":"Loading book","et":"Raamatut laetakse"},"Getting systemupdates":{"fi":"Haetaan järjestelmäpäivityksiä","sv":"Håller på att hämta systemuppdateringar","en":"Getting system updates","et":"Kontrollitakse süsteemi uuendusi"},"comment this page":{"fi":"Kommentoi tätä sivua","en":"Comment this page","sv":"Kommentera denna sida","et":"Comment this page"},"comment type":{"fi":"Kommentin tyyppi","en":"Comment type","sv":"Typen av kommentaren","et":"Kommentaari liik"},"general":{"fi":"Yleinen","en":"General","sv":"Generell","et":"Üldine"},"content":{"fi":"Sisältö","en":"Content","sv":"Innehåll","et":"Sisu"},"system":{"fi":"Järjestelmä","en":"System","sv":"System","et":"Süsteem"},"layout":{"fi":"Ulkoasu","en":"Layout","sv":"Layout","et":"Paigutus"},"my comment":{"fi":"Kommenttini","en":"My comment","sv":"Min kommentar","et":"Minu kommentaar"},"tablefill":{"fi":"Täytä taulukko","sv":"Fyll i tabellen","en":"Fill table","et":"Täida tabel"},"fillsd":{"fi":"Täytä päättelyketju","sv":"Fyll i härledningen","en":"Fill derivation","et":"Täida lahenduskäik"},"ordersd":{"fi":"Järjestä päättelyketju","sv":"Ordna härledningen","en":"Order derivation","et":"Järjesta lahenduskäik"},"openemathcenter":{"fi":"Avaa E-Mathcenter","sv":"Öppna E-Mathcenter","en":"Open E-Mathcenter","et":"Ava E-Mathcenter"},"Show mqpanel":{"fi":"Näytä matikkapaneli","sv":"Visa matematikpanelen","en":"Show mathpanel","et":"Näita matemaatikapaneeli"},"Hide mqpanel":{"fi":"Piilota matikkapaneli","sv":"Göm matematikpanelen","en":"Hide mathpanel","et":"Peida matemaatikapaneel"},"markings":{"fi":"Merkinnät","sv":"Markeringarna","en":"Markings","et":"Märgistus"},"preview":{"fi":"Esikatselu","sv":"Förhandsgranskning","en":"Preview","et":"Eelvaade"},"Calculator":{"fi":"Laskin","sv":"Räknare","en":"Calculator","et":"Kalkulaator"},"presentation view open":{"fi":"Esitystila","en":"Presentation mode","sv":"Presentationsläge","et":"Esitlusvaade"},"course chat":{"fi":"Kurssi-chat","en":"Course chat","sv":"Kurs chat","et":"Kursuse chat"},"please install plugin":{"fi":"Ole hyvä ja asenna E-math-plugin.","en":"Please, install E-math-plugin.","sv":"Vänligen installera E-math pluginen.","et":"Palun installeeri E-math´i plugin."},"click here":{"fi":"Paina tästä","en":"Click here","sv":"Tryck här","et":"Vajuta siia"},"add new key":{"fi":"Lisää uusi avain","en":"Add new key","et":"Lisa uus võti","sv":"Lägg till ny nyckel"},"Getting updates":{"fi":"Haetaan päivityksiä","en":"Getting Updates","et":"Uuendatakse","sv":"Hämtar uppdateringar"},"key already exists":{"fi":"Avain on jo olemassa","en":"Key already exists","et":"Võti on juba olemas","sv":"Nyckeln existerar redan"},"edit done":{"fi":"Muokkaus valmis","en":"Edit done","et":"Muutmisega valmis","sv":"Editeringen är färdig"},"ok":{"en":"Ok","fi":"Valmis","et":"Valmis","sv":"Klar"},"reset updates":{"fi":"Korjaa kirja","en":"Fix book","sv":"Reparera boken","et":"Paranda raamat"},"no books available":{"fi":"Ei kirjoja valittavissa","en":"No books available","et":"Raamat ei ole saadaval","sv":"inga böcker tillgängliga"},"hide modelsolutions":{"fi":"Piiloita malliratkaisut","en":"Hide modelsolutions","et":"Peida mudellahendused","sv":"Göm modellösningarna"},"show modelsolutions":{"fi":"Näytä malliratkaisut","en":"Show modelsolutions","et":"Näita mudellahendust","sv":"Visa modellösningarna"},"offlineuse":{"fi":"Offline käyttö","en":"Offlineuse","et":"Kasutamine offlines","sv":"Användning offline"},"connect book to coursemanagement":{"fi":"Liitä kirja kurssinhallintaan","en":"Connect book to coursemanagement","et":"Lisa raamat kursusele","sv":"Anslut boken till kurshanteringssystemet"},"updateURL":{"fi":"Päivityspalvelimen osoite","en":"Update URL","sv":"Uppdaterings-URL","et":"Uuenda aadressiribal URL-i"}},"dictname":"system"}</data>
<<showDictData>><data>{"ebdict":{"invalid selection":{"fi":"Valitan. Tätä valintaa ei voi käyttää.","sv":"Tyvärr. Den här markeringen kan inte användas.","en":"Can not use this selection.\nSorry.","et":"Vabandust. Seda valikut ei saa kasutada."},"set comment tool on first":{"fi":"Kommentointityökalu pitää olla päällä, jotta voit käyttää tätä toimintoa.","sv":"För att använda denna funktion måste kommenteringsverktyget vara på.","en":"To use this function, you need to have comment tool on.","et":"Selle funktsiooni kasutamiseks peab kommenteerimise tööriist olema sisse lülitatud."},"youre translating":{"fi":"Olet kääntämässä aineistoa kielestä %0 kieleen %1.","sv":"Du håller på att översätta material från språk %0 till språk %1.","en":"You are translating material from language %0 to language %1.","et":"Sa tõlgid materjali keelest %0 keelde %1."},"ADD":{"fi":"Lisää...","sv":"Lägg till...","en":"Add...","et":"Lisa..."},"Home assignments":{"fi":"Merkitse kotitehtävät","sv":"Markera hemuppgifterna","en":"Mark home assignments","et":"Märgi kodused ülesanded"},"Check solutions":{"fi":"Nouda opiskelijoiden ratkaisut","sv":"Hämta studerandenas lösningar","en":"Get students' solutions","et":"Kogu kokku õpilaste lahendused"},"Student management":{"fi":"Opiskelijoiden hallinta","sv":"Administrera studenter","en":"Student management","et":"Õpilaste haldamine"},"Return to teacher view":{"fi":"Palaa opettajan näkymään","sv":"Gå tillbaka till lärarens vy","en":"Return to teacher's view","et":"Tagasi õpetaja vaatesse"},"show student view":{"fi":"Siirry opiskelijan näkymään","sv":"Gå till studentens vy","en":"Change to student's view","et":"Lülitu õpilase vaatele"},"only on assignment page":{"en":"These can be added only on assignment pages.","fi":"Voidaan lisätä vain tehtäväsivuille.","sv":"Kan bara läggas till på uppgiftssidor.","et":"Seda saab lisada ainult ülesannete lehele."},"no assignments":{"en":"No assignments on this page.","fi":"Tällä sivulla ei ole tehtäviä.","sv":"På denna sida finna inga uppgifter.","et":"Sellel lehel ei ole ülesandeid"},"Teachers":{"en":"Added by teacher:","fi":"Opettajan lisäämät:","sv":"Tillagt av läraren:","et":"Õpetaja lisatud:"},"model from student":{"en":"Make a modelsolution from this student's solution.","fi":"Tee tästä oppilaan ratkaisusta malliratkaisu.","sv":"Gör denna uppgiftslösning till en modellösning.","et":"Tee selle õpilase tööst mudellahndus."},"edit teacherelement":{"en":"Edit this teacher's element.","fi":"Muokkaa opettajan lisäämää elementtiä.","sv":"Editera detta av läraren tillagda element.","et":"Muuda õpetaja lisatud materjali."},"delete teacherelement":{"en":"Delete this teacher's element.","fi":"Poista tämä opettajan lisäämä elementti.","sv":"Ta bort detta element tillagt av läraren.","et":"Kustuta see õpetaja poolt lisatud materjal."},"teachers types":{"en":"Change the type of the added content","fi":"Vaihda sisällön tyyppi","sv":"Byt typen av det tillagda materialet","et":"Vaheta sisu tüüpi"},"edit homeassignments":{"en":"Edit homeassignments:","fi":"Muokkaa kotitehtäviä:","sv":"Editera hemuppgifter:","et":"Muuda koduseid ülesandeid:"},"new homeassignments":{"en":"Mark new homeassignments","fi":"Merkitse uusia kotitehtäviä","sv":"Markera nya hemuppgifter","et":"Tähista uued kodused üleanded"},"Evaluate":{"en":"Evaluate","fi":"Arvioi","sv":"Utvärdera","et":"Hinda"},"Modelsolution":{"en":"Make modelsolution","fi":"Malliratkaisuksi","sv":"Skapa en modellösning","et":"Tee mudellahendus."},"homeassignment title":{"en":"Title of homeassignment","fi":"Kotitehtävien otsikko","sv":"Hemuppgiftens rubrik","et":"Koduste ülesannete pealkiri"},"homeassignments":{"en":"Homeassignments","fi":"Kotitehtävät","sv":"Hemuppgifter","et":"Kodused ülesanded"},"own bookmarks":{"en":"Own bookmarks","fi":"Omat kirjanmerkit","sv":"Egna bokmärken","et":"Minu järjehoidjad"},"assignment":{"en":"Assignment","fi":"Tehtävä","sv":"Uppgift","et":"Ülesanne"},"plainText":{"en":"Plain text","fi":"Pelkkää tekstiä","sv":"Endast text","et":"Tavaline tekst"},"multichoise":{"en":"Multichoise quiz","fi":"Monivalintatehtävä","sv":"Flervalsuppgift","et":"Valikvastustega küsimus"},"shortanswer":{"en":"Shortanswer","fi":"Lyhytsyöttötehtävä","sv":"Luckor att fylla i","et":"Lühivastus"},"SDshuffle":{"en":"Shuffled structured derivation","fi":"Sekoitettu päättelyketju","sv":"En blandad härledning","et":"Segamini aetud struktuune lahendus."},"Add incorrect":{"en":"Add incorrect answer","fi":"Lisää väärä vastausvaihtoehto","sv":"Lägg till ett felaktigt svarsalternativ","et":"Lisa vale vastus"},"select dictionary":{"en":"Select dictionary","fi":"Valitse sanasto","sv":"Välj ordlista","et":"Vali sõnaraamat."},"from lang":{"en":"From language","fi":"Kielestä","sv":"Från språket","et":"Keelest"},"to lang":{"en":"To language","fi":"Kieleen","sv":"Till språk","et":"Keelde"},"filter unlocalized":{"en":"Show untranslated only","fi":"Vain kääntämättömät","sv":"Visa endast oöversatt","et":"Näita ainult tõlkimata laused"},"edit dictionary":{"en":"Edit dictionary","fi":"Muokkaa sanastoa","sv":"Editera ordboken","et":"Muuda sõnastikku"},"localization":{"en":"Localization","fi":"Kotoistus","sv":"Lokalisering","et":"Asukoht"},"hide":{"en":"Hide","fi":"Piilota","et":"Peida","sv":"Visa inte"},"Show hidden":{"en":"Show hidden","fi":"Näytä piilotetut","et":"Näita peidetud objekte","sv":"Visa gömda objekt"},"Comments on page":{"en":"Comments on page","fi":"Kommentit sivulla","et":"Lehekülge on kommenteeritud","sv":"Sidans kommentarer"},"initAuthor":{"en":"Initialization","fi":"Alustus","et":"Alustamine","sv":"Startar upp"},"Loading...":{"en":"Loading...","fi":"Lataa...","et":"Laeb...","sv":"Laddar..."},"newsolution":{"fi":"Uusi ratkaisu","en":"New solution","sv":"Ny lösning","et":"Uus lahendus"},"evaluate":{"fi":"Arvioi","en":"Evaluate","sv":"Utvärdera","et":"Hinda"},"modelsolution":{"fi":"Esimerkkiratkaisu","en":"Modelsolution","sv":"Modellösning","et":"Näidislahendus"},"add new solution element":{"fi":"Lisää uusi elementti","en":"Add new element","sv":"Lägg till nytt element","et":"Lisa uus element"},"make modelsolution":{"fi":"Tee esimerkkiratkaisu","en":"Make modelsolution","sv":"Gör en modellösning","et":"Tee näidislahendus"},"solver":{"fi":"Ratkaisija","en":"Solver","sv":"Studerande","et":"Lahendaja"},"wrong clicks":{"fi":"Vääriä painalluksia","en":"Wrong clicks","sv":"Fel tryckningar","et":"Vale klahvikombinatsioon"},"show solvers":{"fi":"Näytä ratkaisijat","en":"Show solvers","sv":"Visa studerande","et":"Näita lahendajaid"},"hide solvers":{"fi":"Piilota ratkaisijat","en":"Hide solvers","sv":"Göm studerande","et":"Peida lahendajad"},"correct solution":{"fi":"Oikea ratkaisu","en":"Correct solution","sv":"Korrekt lösning","et":"Õige lahendus"},"solution":{"fi":"Ratkaisu","en":"Solution","sv":"Lösning","et":"Lahendus"},"sderivation":{"fi":"Rakenteinen päättelyketju","en":"Structured derivation","sv":"Strukturerad härledning","et":"Struktuurne lahendus"},"Make modelsolution":{"fi":"Tee malliratkaisu","en":"Make modelsolution","sv":"Skapa en modellösning","et":"Tee mudellahendus"},"modelsolutions":{"fi":"Malliratkaisut","en":"Modelsolutions","sv":"Modellösning","et":"Näidislahendus"},"select language":{"fi":"Valitse kieli","en":"Select language","sv":"Välj språk","et":"Vali keel"},"displaymode":{"fi":"Keskitetty kaava","en":"Display style formula","sv":"Centrerad formel","et":"Pooleliolev lahendus"},"saving":{"fi":"Tallennetaan","en":"Saving","sv":"Sparar","et":"Salvestatakse"},"deleting":{"fi":"Poistetaan","en":"Deleting","sv":"Tar bort","et":"Kustutakse"},"newmodelsolution":{"fi":"Uusi malliratkaisu","en":"New modelsolution","sv":"Ny modellösning","et":"Uus näidislahendus"},"editmodelsolution":{"fi":"Muokkaa malliratkaisua","en":"Edit modelsolution","sv":"Redigera modellösning","et":"Muuda näidislahendust"},"removemodelsolution":{"fi":"Poista malliratkaisu","en":"Remove modelsolution","sv":"Ta bort modellösning","et":"Eemalda näidislahendus"},"working":{"fi":"Työskennellään","en":"Working","sv":"Vänta","et":"Töös..."},"modelsolution add to this":{"fi":"Joku muu lisäsi uuden malliratkaisun.","en":"New modelsolution was added for this assignment by someone else.","sv":"Någon annan lade till en modellösning","et":"Keegi teine lisas näidislahenduse."},"modelsolution removed":{"fi":"Joku poisti tämän malliratkaisun.","en":"This modelsolution was removed by someone else.","sv":"Någon tog bort denna modellösning","et":"Keegi postitas selle näidislahenduse."},"page locked try later":{"fi":"Sivu on lukossa. Yritä myöhemmin uudelleen.","en":"Page was locked. Try again later.","sv":"Sidan är låst. Försök igen senare.","et":"Lehekülg on lukus. Proovi hiljem uuesti."},"new section":{"sv":"Nytt kapitel","en":"New section","fi":"Uusi kappale","et":"Uus peatükk"},"new chapter":{"fi":"Uusi luku","en":"New chapter","sv":"Nytt kapitel","et":"Uus osa"},"new subsection":{"fi":"Uusi alikappale","en":"New subsection","sv":"Nytt underkapitel","et":"Uus alapeatükk"},"toceditinfo":{"fi":"Opaste","en":"Info","sv":"Hjälp","et":"Info"},"frontpage":{"fi":"Etusivu","en":"Front page","sv":"Framsida","et":"Esileht"},"front":{"fi":"Etusivu","en":"Front page","sv":"Första sida","et":"Esileht"},"chapter":{"fi":"Luku","en":"Chapter","sv":"Kapitel","et":"Peatükk"},"section":{"fi":"Kappale","en":"Section","sv":"Kapitel","et":"Peatükk"},"subsection":{"fi":"Alikappale","en":"Subsection","sv":"Underkapitel","et":"Alapeatükk"},"noheader":{"fi":"Ilman otsikkoa","en":"Without header","sv":"Utan rubrik","et":"Ilma pealkirjata"},"remove":{"fi":"poista","en":"remove","sv":"ta bort","et":"eemalda"},"assignments":{"fi":"Tehtäväsivu","en":"Assignment page","sv":"Uppgiftssida","et":"Ülesannete lehekülg"},"tocicon":{"fi":"Kuvake","en":"Icon","sv":"Ikon","et":"Pilt"},"icon definition":{"fi":"Kuvakkeen selite","en":"Icon definition","sv":"Bildtext","et":"Pildi selgitus"},"extramaterial":{"fi":"Lisämateriaali","en":"Extra material","sv":"Extra material","et":"Lisamaterjal"},"topic":{"fi":"Aihe","en":"Topic","sv":"Ämne","et":"Aine"},"toc item settigns":{"fi":"Asetukset","en":"Settings","sv":"Inställningar","et":"Seaded"},"title":{"fi":"Otsikko","en":"Title","sv":"Rubrik","et":"Pealkiri"},"book settigns":{"fi":"Kirjan asetukset","en":"Book settigns","sv":"Bokens inställningar","et":"Raamatu seaded"},"booktitle":{"fi":"Kirjan otsikko","en":"Title of the book","sv":"Bokens titel","et":"Raamatu nimi"},"bookauthors":{"fi":"Kirjoittajat","en":"Authors","sv":"Författare","et":"Autorid"},"booksecondaryauthors":{"fi":"Kirjan muut kirjoittajat","en":"Secondary authors of the book","sv":"Bokens övriga författare","et":"Raamatu kaasautorid"},"parameters":{"fi":"Parametrit","en":"Parameters","sv":"Parametrar","et":"Parameetrid"},"is extramaterial":{"fi":"Lisämateriaalia","en":"Extra material","sv":"Extra material","et":"Lisamaterjal"},"subsectiontype":{"fi":"Alikappaletyyppi","en":"Subsection type","sv":"Underkapitel typ","et":"Alapeatüki tüüp"},"textpage":{"fi":"Tekstisivu","en":"Text page","sv":"Text sida","et":"Teksti lehekülg"},"select type":{"fi":"Valitse tyyppi","en":"Select type","sv":"Välj typ","et":"Vali tüüp"},"no headimage":{"fi":"Ei otsikkokuvaa","en":"No headimage","et":"Pealkirja pilt puudub","sv":"Ingen rubrikbild"},"headimage":{"fi":"Otsikkokuva","en":"Headimage","et":"Pealkirja pilt","sv":"Rubrikbild"}},"dictname":"tools"}</data>
/***
|Name|modelsolution.js|
|Version|1.4|
|Author|Petri Salmela, Petri Sallasmaa|
|Type|plugin|
|Requires|jQuery 1.4.3 or newer, jQuery UI 1.8.16 or newer|
|Description|modelSolution element show/edit functionality for TiddlyWiki-ebook|
!!!!!Revisions
<<<
20131213.1458''add'' ''Version 1.4''
* show/hide modelsolutions for Authors and showModelsolution macro
<<<
<<<
20131017.1400''fix'' ''Version 1.3''
* emathfuncgraph: added div with ebelement -class around it.
<<<
<<<
20131017.1023 ''fix'' ''Version 1.2''
* cancel editing returns modelsolution to original state
<<<
<<<
20131011.1111 ''add'' ''Version 1.1''
* added copy functionality
* new icon in colors
<<<
<<<
20131010.0917 ''Version 1.0''
* Class made
<<<
!!!!!Code
//{{{
/*******************************************************************
* modelSolution.js
* modelSolution element show/edit functionality for TiddlyWiki-ebook
* Petri Salmela
* Petri Sallasmaa
* 13.08.2013
*******************************************************************/
/***********************************************
* EbmodelSolution -class
* One modelSolution element
***********************************************/
EbmodelSolution = function(options){
options = options || {};
this.tiddlerName = options.tiddlerName || '';
this.place = jQuery(options.place) || jQuery('<div></div>');
this.editable = !!options.editable;
var pagenum = jQuery('.bookpage').index(this.place.parents('.bookpage'));
this.pagenum = (pagenum == -1) ? false : pagenum;
this.assignment = options.assignment || '';
this.elemtype = 'modelsolution';
this.title = options.title || '';
this.elements = [];
this.creator = '';
this.modelsolutionAnswer = '';
this.ispublic = false;
this.initPanels();
}
EbmodelSolution.prototype.initPanels = function(){
// Init available panelsets.
this.panels = {
// Creating new solutions.
create: [
{
name: 'newmodelsolution',
text: EbookDictionary.localize('newmodelsolution', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-newdoc-color"><path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="green" style="stroke: none;" d="M17 12 l7 0 l0 7 l7 0 l0 7 l-7 0 l0 7 l-7 0 l0 -7 l-7 0 l0 -7 l7 0z" /></svg>',
click: function(event){
var t = new Authortool();
t.solutions_length = jQuery(this).parents('.assigmentSolution').find('.solutiontabs li').length;
t.assignmentTiddler = event.data.modelsolution.place.parents('[tiddler]').eq(1).attr('tiddler');
t.scroll = jQuery('#pageOneWrapper').scrollTop()+jQuery(this).parent().parent().height();
t.startAuthoring('makemodelsolution');
}
},
{
name: 'editmodelsolution',
text: EbookDictionary.localize('editmodelsolution', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-editdoc"> <path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="blue" style="stroke: none;" d="M19 11 l4 -1 l4 2 l1 4 l-10 15 l-10 5 l2 -11 z m-8.5 15.2 l-1 5 l3 2 l4 -2 a9 9 0 0 0 -6 -5 z m11.5 -15.5 l-10 15 l1 0.5 l10 -15 z m4 2 l-10 15 l0.5 1 l10 -15 z" /></svg>',
click: function(event){
var modelSolution = event.data.modelsolution;
var t= new Authortool();
t.modelSolution = modelSolution;
t.tiddlerName =modelSolution.tiddlerName;
t.oldContent = store.getTiddlerText(modelSolution.tiddlerName);
modelSolution.hasTool = t;
jQuery('#actionButtons').hide();
jQuery('#pageOne h3').unbind('click');
t.startAuthoring('editmodelsolution');
}
},
{
name: 'copymodelsolution',
text: EbookDictionary.localize('copymodelsolution', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-white-copydoc-color"><g transform="scale(0.8)"><path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /></g><g transform="scale(0.8) translate(10 10)"><path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="green" style="stroke: none;" d="M17 12 l7 0 l0 7 l7 0 l0 7 l-7 0 l0 7 l-7 0 l0 -7 l-7 0 l0 -7 l7 0z" /></g></svg>',
click: function(event){
var modelSolution = event.data.modelsolution;
var t= new Authortool();
t.solutions_length = jQuery(this).parents('.assigmentSolution').find('.solutiontabs li').length;
t.assignmentTiddler = event.data.modelsolution.place.parents('[tiddler]').eq(1).attr('tiddler');
t.scroll = jQuery('#pageOneWrapper').scrollTop()+jQuery(this).parent().parent().height();
t.modelSolution = modelSolution;
t.tiddlerName =modelSolution.tiddlerName;
t.copymodelsolution = true;
modelSolution.hasTool = t;
jQuery('#actionButtons').hide();
jQuery('#pageOne h3').unbind('click');
t.startAuthoring('makemodelsolution');
}
},
{
name: 'removemodelsolution',
text: EbookDictionary.localize('removemodelsolution', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-trashdoc-color"> <path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" style="stroke: none; fill: red;" d="M11 12 l7 0 l0 -1 l2 0 l0 1 l7 0 l0 2 l-16 0z m0 3 l16 0 l-3 20 l-10 0z m1.5 2 l2 15 l2 0 l-1 -15z m5 0 l0.5 15 l2 0 l0.5 -15z m8 0 l-3 0 l-1 15 l2 0z" /></svg>',
click: function(event){
var modelSolution = event.data.modelsolution;
var t= new Authortool();
t.tiddlerName =modelSolution.tiddlerName;
t.startAuthoring('removemodelsolution');
}
}
],
control: [
{
name: 'ordermodelsolutions',
text: EbookDictionary.localize('order', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 30 30" class="mini-icon mini-icon-order"><path style="stroke: none;" d="M12 4 a3 3 0 0 0 6 0 a3 3 0 0 0 -6 0z m0 10 a3 3 0 0 0 6 0 a3 3 0 0 0 -6 0z m0 10 a3 3 0 0 0 6 0 a3 3 0 0 0 -6 0z" /><path style="stroke: none; fill: blue;" d="M10 28 a7 12 0 0 1 -3 -24 l0 -3 l5 3 l-5 5 l0 -3 a3 11 0 0 0 1 21.5z" /><path style="stroke: none; fill: red;" d="M22 2 a7 7 0 0 1 2 14 l0 5 l-5 -5 l5 -6 l0 4 a5 6.5 0 0 0 0 -12z" /></svg>',
click: function(event){
// Remember!: var solution = this;
var solution = event.data.modelsolution;
solution.place.addClass('elemsortable')
.find('.modelsolutionset .orderableelems').sortable({placeholder: "ui-state-highlight"})
.find('.ebelement').append('<div class="ordershade"></div>')
.each(function(index){
jQuery(this).attr('solutionelemname', solution.elements[index].data)
.attr('solutionelemtype', solution.elements[index].type);
});
}
},
{
name: 'savemodelsolution',
text: EbookDictionary.localize('save', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-savedoc-color"> <path style="stroke: none;" d="M5 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M6 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="blue" style="stroke: none;" d="M12 14 l22 0 l4 4 l0 22 l-26 0z m6 2 l0 7 l14 0 l0 -7z m9 1 l3 0 l0 5 l-3 0z m-12 9 l0 12 l20 0 l0 -12z" transform="scale(0.8 0.8)" /></svg>',
click: function(event){
// Remember!: var solution = this;
jQuery(this).trigger('elementset-save');
}
},
{
name: 'cancelmodelsolution',
text: EbookDictionary.localize('cancel', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 30 30" class="mini-icon mini-icon-cancel"><path style="stroke: none; fill: #a00;" d="M1 15 a14 14 0 0 0 28 0 a14 14 0 0 0 -28 0z" /><path style="fill: red; stroke: none;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 1 -26 0z"/><path style="fill: white; stroke: none;" d="M6 10 l4 -4 l5 5 l5 -5 l4 4 l-5 5 l5 5 l-4 4 l-5 -5 l-5 5 l-4 -4 l5 -5 z" /><path style=" stroke: none; fill: white; opacity: 0.4;" d="M2 15 a13 13 0 0 1 26 0 a13 13 0 0 0 -13 0 a13 13 0 0 1 -13 0z" /></svg>',
click: function(event){
jQuery(this).trigger('elementset-cancel');
}
}
],
ordermode: [
{
name: 'orderready',
text: EbookDictionary.localize('ready', this.pagenum),
click: function(event){
// Remember!: var solution = this;
var solution = event.data.modelsolution;
solution.place.removeClass('elemsortable')
.find('div.modelsolutionset').sortable('destroy')
.find('div.ordershade').remove();
var elementlist = solution.place.find('div.ebelement').map(function(){
var soldata = jQuery(this).attr('solutionelemname');
var soltype = jQuery(this).attr('solutionelemtype');
return new EbElement({"type": soltype, "data": soldata}, true);
}).toArray();
solution.elements = elementlist;
solution.save();
}
},
{
name: 'ordercancel',
text: EbookDictionary.localize('cancel', this.pagenum),
click: function(event){
// Remember!: var solution = this;
var solution = event.data.modelsolution;
solution.place.removeClass('elemsortable');
solution.show();
}
}
],
publish: [
{
name: 'publish',
text: EbookDictionary.localize('publish', this.pagenum),
icon: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30" height="30" viewbox="0 0 40 40" class="mini-icon-bg mini-icon-bg-publishdoc-color"> <path style="stroke: none;" d="M2 2 l23 0 l8 8 l0 28 l-31 0 z" /><path class="iconbackground" fill="white" style="stroke: none;" d="M3 3 l0 34 l29 0 l0 -26 l-8 0 l0 -8 z" /><path class="iconcontent" fill="green" style="stroke: none;" d="M5 20 a30 30 0 0 0 15 0 l0 -4 l7 7 l-7 7 l0 -5 a30 30 0 0 1 -15 2z" transform="scale(1.3 1.3) rotate(-8)"/></svg>',
click: function(event){
// Remember!: var solution = this;
var solution = event.data.modelsolution;
solution.ispublic = true;
solution.save();
var t = new Teachertool();
t.modelsolution = solution.tiddlerName;
t.startAuthoring('publishmodelsolution');
solution.show();
}
}
]
}
}
EbmodelSolution.prototype.getPanel = function(){
// Return jQuery-object with panels.
var solution = this;
var availPanels = [];
var tablist = this.place.parents('.solutioncontent').prev().find('.solutiontablist');
if (typeof(Teachertool) === 'function' && typeof(Authortool) !=="function") {
if(!this.ispublic){
availPanels.push('publish');
}
/*Check panels!
availPanels.push('teacher');
availPanels.push('Teachertool');
*/
} else if (this.editable && this.pagenum === 0) {
availPanels.push('control');
availPanels.push('ordermode');
} else if (tablist.length > 0 && tablist.find('li.editable').length === 0 && this.pagenum === 0) {
availPanels.push('create');
}
var panel = jQuery('<div class="modelsolutionsettoolbar"></div>');
for (var i = 0; i < availPanels.length; i++) {
var paneltype = availPanels[i];
var subPanel = jQuery('<div class="modelsolution'+paneltype+'bar modelsolutionsubtoolbar"></div>');
var buttonset = this.panels[paneltype];
for (var j = 0; j < buttonset.length; j++) {
var butContent = buttonset[j].icon || buttonset[j].text;
var button = jQuery('<button class="'+buttonset[j].name+' ebook-button" title="'+buttonset[j].text+'">'+butContent+'</button>');
button.bind('click', {modelsolution: this}, buttonset[j].click);
subPanel.append(button);
}
panel.append(subPanel);
}
return panel;
}
EbmodelSolution.prototype.getModelsolutionsToolbar = function(){
// Return a solutionsToolbar.
var solution = this;
try{
var solutionButtons = DataTiddler.getData(store.getTiddler(this.tiddlerName).fields.solutionto, 'availableButtons', []);
}catch(e){
var solutionButtons =[];
}
if(solutionButtons.length === 0){
var teacherelementsToAddInittiddlers = store.getTaggedTiddlers('teacherAddElement');
for(var i = 0; i < teacherelementsToAddInittiddlers.length; i++){
solutionButtons.push(teacherelementsToAddInittiddlers[i].data('addElement'));
}
}
var solutionsToolbar = jQuery('<div class="solutiontoolbar" title="'+EbookDictionary.localize('add new solution element', this.pagenum)+'"></div>');
for (var i = 0; i < solutionButtons.length; i++){
if (typeof(elementFunctions[solutionButtons[i].addFunction]) === 'function'){
var buttoncontent = solutionButtons[i].icon || EbookDictionary.localize(solutionButtons[i].elementType, this.pagenum);
solutionsToolbar.append('<button buttonListNro="'+i+'" class="add'+solutionButtons[i].elementType+' ebook-button" title="'+EbookDictionary.localize(solutionButtons[i].elementType, this.pagenum)+'">'+buttoncontent+'</button>');
}
}
solutionsToolbar.find('button.ebook-button').click(function(){
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
elementFunctions[solutionButtons[jQuery(this).attr('buttonListNro')].addFunction](solution);
config.options.chkAutoSave = autosaveStatus;
solution.focusFirts=false;
solution.show();
});
return solutionsToolbar;
}
EbmodelSolution.prototype.initElements = function(){
var modelsolutiondata = DataTiddler.getData(this.tiddlerName, "modelsolution", {"modelsolutionAnswer":"","creator":"","modelsolutionelements":[], "editable": true, "ispublic":false,"title":"","elemtype":"modelsolution"});
this.creator = modelsolutiondata.creator || config.options.txtUserName;
this.modelsolutionAnswer = modelsolutiondata.modelsolutionAnswer || "";
this.editable = !!modelsolutiondata.editable;
this.ispublic = !!modelsolutiondata.ispublic;
this.elemtype = modelsolutiondata.elemtype || "modelsolution";
this.title = modelsolutiondata.title;
var elements = modelsolutiondata.modelsolutionelements || [];
for (var i = 0; i < elements.length; i++){
var elem = new EbElement(elements[i], this.editable);
this.addElement(elem);
}
}
EbmodelSolution.prototype.editElements = function(){
var modelsolutiondata = DataTiddler.getData(this.tiddlerName, "modelsolution", {"modelsolutionAnswer":"","creator":"","modelsolutionelements":[], "editable": true, "ispublic":false,"title":"","elemtype":"text"});
var elements = modelsolutiondata.modelsolutionelements || [];
this.elements = [];
for (var i = 0; i < elements.length; i++){
var elem = new EbElement(elements[i], this.editable);
this.addElement(elem);
}
}
EbmodelSolution.prototype.save = function(){
var modelsolutiondata = {
"creator": this.creator,
"modelsolutionAnswer": this.modelsolutionAnswer,
"editable": this.editable,
"ispublic": this.ispublic,
"elemtype": this.elemtype,
"title": this.title,
"modelsolutionelements": []
}
for (var i = 0; i < this.elements.length; i++){
modelsolutiondata.modelsolutionelements.push(this.elements[i].getData());
}
var autosaveStatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
DataTiddler.setData(this.tiddlerName, 'modelsolution', modelsolutiondata);
config.options.chkAutoSave = autosaveStatus;
}
EbmodelSolution.prototype.addElement = function(element){
this.elements.push(element);
}
EbmodelSolution.prototype.removeElement = function(index){
this.elements.splice(index, 1);
this.save();
}
EbmodelSolution.prototype.getWiki = function(){
var wikitext = '{{modelsolutionset{\n';
var ending = '}}}';
wikitext += '{{orderableelems{\n';
for (var i = 0; i<this.elements.length; i++){
if(this.editable && this.elements[i].type =="emfuncgraph"){
wikitext += '{{ebelement{\n' +elementFunctions['getWikiemfuncgraph'](this.elements[i].data,' author') + '}}}\n';
}else{
wikitext += this.elements[i].getWiki();
}
}
wikitext += '}}}';
wikitext += '{{solutionanswer{\n'+EbookDictionary.localize('answer', this.pagenum)+'{{solutionanswerbox{'+this.modelsolutionAnswer+'}}} }}}';
wikitext += ending;
return wikitext;
}
EbmodelSolution.prototype.show = function(){
var modelSolution = this;
var pagenum = jQuery('.bookpage').index(this.place.parents('.bookpage'));
var tiddlername = this.tiddlerName;
this.place.empty();
wikify(this.getWiki(), this.place[0], null, store.getTiddler(this.tiddlerName));
if (!this.editable){
this.place.find('.modelsolutionset:last a.button.command_qededit').remove();
if(typeof(Teachertool)==="function" && pagenum === 0){
/*TODOO teacher
*/
}else if(typeof(Authortool)==="function" && pagenum === 0){
/*
*/
}
} else {
if(typeof(Authortool)==="function" && pagenum === 0){
if(tiddlername =="creatingModelsolution"){
var t= new Authortool();
t.modelSolution = modelSolution;
t.tiddlerName =tiddlername;
modelSolution.hasTool = t;
t.callFifo.push('sendContent');
t.callFifo.push('removeLock');
t.callFifo.push('getUpdates');
t.callFifo.push('removeworkingDialog');
modelSolution.hasTool.editModelsolution();
}else{
if(!modelSolution.hasTool){
var t= new Authortool();
t.modelSolution = modelSolution;
t.tiddlerName =tiddlername;
t.startAuthoring('editmodelsolution');
modelSolution.hasTool = t;
jQuery('#actionButtons').hide();
jQuery('#pageOne h3').unbind('click');
}else{
modelSolution.hasTool.editModelsolution();
}
}
}
}
this.place.prepend(this.getPanel());
this.place.append(this.getPanel());
if (this.editable && this.pagenum === 0) {
this.place.find('.command_qededit').click();
}
this.place.find('.modelsolutionset:last a.button.command_editorclose').remove();
}
config.macros.modelsolution = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var modelsolution = tiddler.data('modelsolution', {"creator":"","modelsolutionelements":[]});
var editable = ((modelsolution.creator == config.options.txtUserName) || typeof(Authortool) ==="function") && modelsolution.editable;
jQuery(place).append('<div tiddler="'+tiddler.title+'" class="modelsolutionsetwrapper"></div>');
place = jQuery(place).find('.modelsolutionsetwrapper:last')[0];
var modelsolutionElement = new EbmodelSolution({"tiddlerName":tiddler.title, "place": place, "editable":true});
modelsolutionElement.initElements();
modelsolutionElement.show();
}
}
//}}}
//{{{
config.macros.showModelsolution = {
/**********************************************
* Show Modelsolutions
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var assignmentTiddler = jQuery(place).attr('tiddler');
var possiblesolutions = store.reverseLookup('modelsolutionto',assignmentTiddler, true, 'created');
var solutions = [];
var modeltype="";
var modeltags=[];
var pageId = jQuery(place).parents('.bookpage').attr('id');
switch(pageId){
case "pageOne":
var pageNro = 0;
break;
case "pageTwo":
var pageNro = 1;
break;
default:
var pageNro = 0;
break;
}
var defaultlang = Emathbook.options.pages[pageNro]["defaultlang"];
var pagelang = Emathbook.options.pages[pageNro].lang;
var pageTiddler = EbookPages[pageNro].ebook.getContentById((EbookPages[pageNro].currentpage));
if(typeof(Authortool)==="function"){
modeltype = "author";
solutions = possiblesolutions;
}else if(typeof(Teachertool)==="function"){
modeltype = "teacher";
for (var i=0;i<possiblesolutions.length;i++){
if (possiblesolutions[i].data('modelsolution') && possiblesolutions[i].data('modelsolution').creator.toLowerCase() === config.options.txtUserName.toLowerCase()){
solutions.push(possiblesolutions[i]);
}
}
}
if(solutions.length == 0){
jQuery(place).append('<button class="startSolution">'+EbookDictionary.localize('Make modelsolution')+'</button>')
.find('.startSolution').click(function(){
if( modeltype === "author"){
var t = new Authortool();
t.solutions_length = solutions.length;
t.assignmentTiddler = assignmentTiddler;
t.scroll = jQuery('#pageOneWrapper').scrollTop()+jQuery(this).parent().parent().height();;
t.startAuthoring('makemodelsolution');
} else if ( modeltype === "teacher"){
}
jQuery(this).remove();
}).button();
}else{
var soltabs = jQuery('<div class="modelsolutionlist listhidden"><h3>'+EbookDictionary.localize('modelsolutions')+'<span class="hidelist listvisibility">'+EbookDictionary.localize('hide modelsolutions')+'</span><span class="noclick showlist listvisibility">'+EbookDictionary.localize('show modelsolutions')+'</span></h3><div class="solutiontabs"><ul class="solutiontablist"></ul></div></div>');
var sollist = soltabs.find('ul.solutiontablist');
var visibilityButtons = soltabs.find('span.listvisibility');
var solcontent = jQuery('<div class="solutioncontent"></div>');
var hasnonEditable = false;
for (var i = 0; i < solutions.length; i++){
sollist.append('<li tiddler="'+solutions[i].title+'" class="'+solutions[i].fields.elementlanguage+'"><a href="javascript:;">'+solutions[i].fields.elementlanguage+" : "+(i+1)+'</a></li>');
if(solutions[i].data('modelsolution') && solutions[i].data('modelsolution').editable){
sollist.addClass('iseditable').attr('iseditable',solutions[i].title);
}
}
jQuery(place).append(soltabs).find('.modelsolutionlist').append(solcontent);
visibilityButtons.click(function(){
jQuery(this).parent().parent().toggleClass('listhidden');
if(jQuery(this).hasClass('noclick')){
sollist.find('li a').last().click();
jQuery(this).removeClass('noclick');
}
});
if(!sollist.hasClass('iseditable')){
sollist.find('li a').click(function(){
var tablist = jQuery(this).parents('ul.solutiontablist');
var contentplace = jQuery(this).parents('.solutiontabs').next();
var solutiontiddler = jQuery(this).parents('li').attr('tiddler');
tablist.find('li').removeClass('currenttab');
jQuery(this).parents('li').addClass('currenttab');
contentplace.empty();
wikify('<<tiddler [['+solutiontiddler+']]>>', contentplace[0], null, tiddler);
});
sollist.find('li').last().addClass('currenttab');
// sollist.find('li a').last().click();
}else{
var selectedModel = sollist.attr('iseditable');
sollist.find('li[tiddler="'+selectedModel+'"]').addClass('currenttab');
wikify('<<tiddler [['+selectedModel+']]>>', solcontent[0], null, tiddler);
}
}
}
}
//}}}
!usage
{{{[img[nextpage.png]]}}}
[img[nextpage.png]]
!notes
//none//
!type
image/png
!file
./nextpage.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANgAAADYABpllopAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAE/SURBVDiNrdWxS8NAFMfx3ztSRamLi1M3J3WrTS86iOAoLlqwq/+AgqDgooOLnQTn4maFJILipougNJdYcLCi6NbJuajYSp6LQQSjaZPvdHDvPjc+YmYkmQgOR0pOH3p6JjHQZ5rSfPFgOcbWaW28Pzb4VR+IN98/tHvbzReTAAEADGSY6cBU8tJUMhsbDCJgkgDPUrJcUXIoNvjtYikFPFpufs28G+uJCwYNgGmHmum66RhzSYBBw0R8bCp5Znv6aBIgAICAGfbFje0Ye2Z1YjA2GJbW7UMGzoXwV+Zzbj0u+MRMqwVZPfntshOwCeJtTr/sFkZuW2FDUUAGsN8GNoq6ev5v+E+QgSsAy4W8U4vwcThIQAPE6wu6qkSFwsA3MJV6U+3SbPb6tVPsByiIL1rCLy/m3EY3UBAlvQI+AcEAafXzIUBoAAAAAElFTkSuQmCC
{{center{
[img[emath-logo-blue.png]]}}}
<<tiddler cb-disclaimer>>
!usage
{{{[img[note_pad.png]]}}}
[img[note_pad.png]]
!notes
Image for theme "notes".
!type
image/png
!file
./data/images/note_pad.png
!url
!data
data:image/png;base64,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
//{{{
config.commands.saveTiddler.handler =function (event, src, title) {
var newTitle = story.saveTiddler(title, event.shiftKey);
if (newTitle) {
story.displayTiddler(null, newTitle);
};
if (newTitle.substring(0,11)=="assignment_" || newTitle.substring(0,14)=="theory_shuffle" || newTitle.substring(0,10)=="theorybox_" || newTitle.substring(0,12)=="textelement_" || newTitle.substring(0,11)=="subsection_" || newTitle.substring(0,8)=="section_" || newTitle.substring(0,11)=="examplebox_" || newTitle.substring(0,21)=="ebook_assignmentlist_" || newTitle.substring(0,8)=="chapter_" || newTitle.substring(0,13)=="graphelement_" || newTitle =="SettingsEbook"){
if(typeof(Emathbook.sendContent)=="function"){
Emathbook.sendContent(newTitle);
}
}
return false;
}
//}}}
<html><h1 class="ebooktitle">Ei kirjoja valittavissa</h1></html>
<<tiddler [[noBooks]]>>
<<pageinit 0>>
<html><h1 class="ebooktitle">Ei kirjoja valittavissa</h1></html>
<<tiddler [[noBooks]]>>
<<pageinit 1>>
!usage
{{{[img[pageside-left.png]]}}}
[img[pageside-left.png]]
!notes
//none//
!type
image/png
!file
./pageside-left.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADBSURBVFiF7ZbBDYMwDEV/qi7hrJE9GCMZAzEGjMEeXoOM4Z4iVRWgUDmNK/FuRBB/P/uAExFc5PIHZzw0L/uGZ+2LOWcBACJSDWDfADMLAHjvmwSwa2BZFgGAEELTAPYMTNPUZNuPsGMgpdR024/ob2AYhp/O/JPuBu4Ad4A7QPUfUSHnrFKYiBzwTwa2bVMpGEJw78/2DTCzSqEYo9s7t2tAa9vHcdztvGDPgNa2z/N82nnBjgGtma/rWtV5obuBF1RJLlRPjvTIAAAAAElFTkSuQmCC
!usage
{{{[img[pageside-right.png]]}}}
[img[pageside-right.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC4SURBVFiF7ZfBDcMgDEU/VZZgDvbIGszBGt7Ja+Ax3EPqqlJbpagoEMI7I/nrnR5OVRV1cSWPb5WPF1N9gIioiPxsdTwDBjMrM++aGNeAQURKRF9NjG/ASClpSunNxHUMGDFGjTE+TTQ3sLQ6vK6rAh0YmAPmgDlgwaPhSiqmJl0YAAB47x2wlcyRA/oxYIQQHLCVzBEDmhtwex+jTxXzDzlnAICIADiDAeO1YmpwPgOGlUwtmhu4A1zxReXWffpHAAAAAElFTkSuQmCC
!usage
{{{[img[pageside-rightcenter.png]]}}}
[img[pageside-rightcenter.png]]
!notes
//none//
!type
image/png
!file
./pageside-rightcenter.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAiCAYAAAAge+tMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAL4SURBVFiF7Zc/T9tAHIbf+5M724kTCkKAaAeGolaqlKFbF1YmBr5EpEplgH6BfIAuVOqQsUMnPgJztzBVYq6IaiQEgtiOc7bj64It8g8IdSFIeaSfLolyd8/99OoskziOQ6WUp5TylVJ+GIbpZ08p9UcpdRxF0XEQBMebm5u/AWgMcHh4WGGMvZFSvpVSvpFSvpZSVoQQJcMwylLKBSllWQghGWNkcP41434fCQdQAPDiukaitQYhBAcHB6etVuvHycnJdymlWlpa2l5dXd22bfs953zYhJBsvtZD5/0nhne7nWUAu+12e5dSiuXl5dxEHMfRALCysnKvzk8qDgBwXReU0odMzY2n3X0EzWZTN5vNO3M1deL3ZWrFG42GbjQaYzs/teJ3MfXi9Xpd1+v1oc5Pvfg4no14rVbTtVot6/yzER/kQQ+gp2Rra0sDz7jjM/HHZib+2MzEHxt+dnaWfdFag3MOSimEEBBCoFAowPd9RFE0dhFKKaSUsCwLpmlCSgnGGCilSJIESikopbI9chEfXIgQAsYYGGMQQsC2bSwuLkJrDdd1USqV4DgOGGNYX1/H2toabNvO3i9Hkff7JgBwx3FACMmKUpqNnPO+KpfLqFarqFarQ2JRFCGO46ySJIHWOhtvVi7ikywmhIBhGDAMAwDQ7XbR7XYRhmEuMpPAj46OsjzeHBljmWRaYRgiDEO02+2+RZIkyQ6RVq/XQ6/XQ5IkfWOuHY/j+M4/EkJQLBYxNzeHSqUCALi6usLl5SV83/8vOb4Nfnp62pfxNN9p529m3PM8eJ6HVqvVt0h6+LTSDo/K95NmXEoJAFBKPV3GJ7lV0owPMtjx2a1yCxNlfNytMsv4BPCNjY3P5+fnHy8uLl65rlsIgmDs9Tgu42MX5xymacK27Wh+fv5kYWHh297e3pc8xMmobu/v77/zPO9TEAQffN9/2el0ip1Oh4dhSNJHeypWKBQghNCWZcWWZfnFYrFlmubPUqn0dWdn51cekqP4C3s7Aby1Sog7AAAAAElFTkSuQmCC
!usage
{{{[img[paperrip.png]]}}}
[img[paperrip.png]]
!notes
Ripped paper
!type
image/png
!file
./paperrip.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAA4CAYAAACPKLr2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAATnSURBVGiB7ZpdSFtnGIDfmBOj4tzo6NrmQOta7bKyWW0oo40gw1uvKuvYGIIMvFA2vNAVNh3awTZhY7uxyTEnGl3nRJpu6c90KjIUyeIUf7AEf4L29MRsEtPkJBq++PPuZpGT+BdzSunFeeC7yPu+3/s95+Tq4z2AiJDI6uzs/NJkMukOqjGbzZqurq5fWZYtSLRv/LJarUaGYc5Ffycq98ny8jIODw8/6e7uTo3PNzQ0UGazufb3qTHiCgvocDi4hoYGKr6OYZi3WZY9tt85HR0dRSsrKzg4ODjPMIxql6DBYCiwWCw/GQyGt6Ixi8XyAcdx24QQFAQBTSZTedyhKpvNNriysoKPNoL4aCOIa2tr+ODBgxGGYTIQEW7dunXWarWOTE1N4cDAgKu5uTkzXo5l2Zzx8fEAIQT9fj/evn37hxhBg8GgdzgcYUIITk5ObrAsW8my7Icul2uLEILRdffuXZO4cXt7+89erxcJITuChBBcW1vDnp6e2ba2NvP4+HgkHA4jIQTX19ext7f3L/EbbmlpyXc4HEHxOZOTkxsMw7wMiAhGo/Ga3W6PiAs8Hg9yHIfiGCEE+/r6HKLG551O505OLHjQCgaDeP/+fRsiKliWzZmenibxNYFAAE0m06dKjUbzuU6nY/Lz85UgIj09HTIzMyGeQCCQSdP0twAAPp+vpaCg4M1ozqfYAgCAY6jctU+MUqkEjUbzxsOHDzXZ2dmf5eXlnYyvoSgKVldXtQq73Y6XLl06sKEYt9sN/f39JampqSNFRUVemqZ3bBZSIgAAkLOdmlAvQRBArVaDWq3eM+90OoHKyspKWA4AgKZpyM3NvScIwt9iuWQ47GyVSgVUMo31en3K5ubmO0lZHZGUZDdSVFLPdmSSFnxeyIJSkQWlIgtKRRaUiiwoFVlQKrKgVGRBqbzwgtR8FgULytAzaRa9di4oIs+kH/USBVSusAk5r+2+/ybDUa+dh/YL/vPi/8WyoFRkQanIglKRBaUiC0pFFpSKLCgVWVAqz0UwFEr+SrGvoMfjgbm5uaQbR1lfX4eqqipnJJLcPSWF47g9E1arda60tPQLn88nxQ/m5+exq6srf2hoiBx179OnTyHl5s2bv/E8H5PgeR6am5s/mp2d/bq1tXUx0YYKBBD8AfB6vWJBAREjLMt+td9b9Hq9sL29HRNDRLhz5w4PAJBaUVHhEQQBo0Pr69ev90RHrsePH8+Znp6OGZVyHIednZ04MTERE19aWsLCwsJ7er3e5na7kRCCtbW1fyAiAIDCZrOF48euY2NjSNO0obGxMRQKhXbiCwsLqNVqrwEiglqtPtfb27tFCEGj0SgAgFo8tC4vL7cuLi7i6OgoVldXhzQazTcAkF1cXPxd9MGWlpbw6tWrv0RlSktL7S6XCy9evPhutM+VK1c+5nk+RrC+vv7P//ecrKmpWY32a2pqcsdM3Ovq6kYfP36Mp0+f1seP6wEgLSMjox4A3gMAlSiu7O7uDhNC8MaNG2Nxe9SnTp36HgAU4nhlZeWY3+9HQgjyPI80TZ8X7Xm1rKzsSUdHx1ZaWtrrMYIXLlwobmtr8xz1K43CwsKqmZkZPHHixNlE6gHglZKSkhmn04kWi+XfPfIqANDu+dWHVqstSeZTEp1O9+NR6gFAcebMmfrLly+/f1jtf9MLA0CGCqjeAAAAAElFTkSuQmCC
!usage
{{{[img[papersquare.png]]}}}
[img[papersquare.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACLSURBVFiF7dexDcMwDETRT8eFC5Xef8cALqxGTOMN7lIYuDcA8SmokGrO2ZhctQAYvblG4psE3NXcZdsXMAf+QwJVCVQlUJVAVQJVCVQlUJVA1X7Vsr2Cv8+T37X20fWCExy9MVzfiGfdc31MA19wBxOoSqAqgaoEqhKoSqAqgaoEqnbnsKPLOQ6AH1t/FkzhsKZQAAAAAElFTkSuQmCC
!usage
{{{[img[prevpage.png]]}}}
[img[prevpage.png]]
!notes
//none//
!type
image/png
!file
./prevpage.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANgAAADYABpllopAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFNSURBVDiNrdSxS8NQEAbw7x5pBbWLi1O3CmIdBG1eooIIuirYZqibuLgIbi4OdhEUBP0HXFuIdRBHwUn70tBNBcHNycXFgqCScwpIJTXtyze+O35vuOOImZFkhC5Q883shWctaoNXrZnBc2XvG4F4CpgWwnejH6zelGWwcQjibGetJ9D1rGkApwSai+qJBVY9azQFHBCwAYC69XYF3cfJNLWHdlKgPQCZOJ9Hgq6yV4iGjwHk4kCRYN0380EgToiw1Av0B3QbsyOCuMIktqjP6QMJLHYk6Nh3b0WrsU0imGLgWhsMUyw0HxyplplpFcCzNhjGsRqXnGnnQbwL4F0bBABn4v6zZHpHX8AYgDMA/56mWEMpS/VakmqTgQIDt9pgGEeqliPVPBGvE/CiDYYpml51wPgeB1MFwMfvGule7JpvZtOByK1JdZMI2JkfKZVhkZWdoncAAAAASUVORK5CYII=
/***
|''Name:''|jquery.pssignchart.js|
|''Author:''|Petri Salmela / Petri Sallasmaa|
|''Description:''|Tool for creating and showing a signchart. jQuery-plugin|
|''Version:''|1.0|
|''Date:''|November 7, 2012|
|''Source:''| http://pesasa.github.com/pssignchart/ |
|''License:''|[[GNU AGPL|http://www.gnu.org/licenses/agpl-3.0.html]]
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
|''lastfix:''|macro, authormode(201309301050)|
***/
//{{{
/*********************************************************
* jquery.pssignchart.js
* jQuery-plugin for creating a sign chart
* Petri Salmela
* pesasa@iki.fi
* 15.08.2012
*
* License: GNU AGPL
********************************************************/
(function($){
// jQuery plugin
$.fn.pssignchart = function(options){
// Test for numberline commands and trigger command with options.
if (typeof(options) === 'string'){
var cmd = options;
options = arguments[1] || {};
if (typeof(options) === 'string'){
options = {name: options};
}
if (typeof(options) === 'undefined'){
options = {}
}
// Placeholder variable for returning value.
options.result = this;
this.children('div.pssignchart').trigger(cmd, options);
return options.result;
}
// Extend default settings with user given options.
var settings = $.extend({
width: 'auto', // width of sign chart. Defaults to width of parent element (auto)
color: 'red', // highlight color
theme: "pssc_default", // html class for styling
mode: 'view',
caption: ''
}, options);
// Return this so that methods of jQuery element can be chained.
return this.each(function(){
// Create new Pssignchart object.
var signchart = new Pssignchart(this, settings);
//testilogit.signchart = signchart;
// Init the signchart
signchart.init();
});
}
var Pssignchart = function(place, settings){
// Constructor for Pssignchart object.
this.settings = settings;
this.mode = settings.mode;
this.caption = this.settings.caption;
this.place = $(place);
this.place.html('<div></div>').addClass('pssignchartwrapper');
this.place = this.place.find('div');
this.place.addClass('pssignchart');
this.rows = [];
this.roots = [];
this.total = {func: '', signs: [''], relation: '\\lt'};
this.intervals = [];
this.rootpoints = [];
this.undefinedpoint = [];
if ($('head style#psscstyle').length == 0){
$('head').append('<style id="psscstyle" type="text/css">'+Pssignchart.strings['style']+'</style>');
}
}
Pssignchart.prototype.init = function(){
// Init and draw the signchart
var signchart = this;
if (this.place.hasClass('pssc_rendered')){
return false;
}
if (this.settings.width == 'auto'){
this.width = this.place.width();
} else {
this.width = this.settings.width;
}
this.place.addClass('pssc_rendered').addClass(this.settings.theme);
var $schart = $('<div class="pssc_tablewrapper"><table class="pssc_table"><caption>'+this.caption+'</caption><thead class="pssc_head"><tr><td colspan="2"><div></div></td></tr></thead><tbody class="pssc_body"></tbody><tbody class="pssc_intervals"><tr></tr></tbody></table></div>');
this.schartnumber = -1;
while ($('#signchart_'+(++this.schartnumber)).length > 0){};
$schart.attr('id','#signchart_'+this.schartnumber)
this.place.empty().append($schart);
this.captionelem = $schart.find('caption');
this.draw();
this.initEvents();
if (this.mode === 'edit'){
this.place.addClass('editmode');
this.showEdit();
} else {
this.place.removeClass('editmode');
}
return this;
}
Pssignchart.prototype.draw = function(){
// Draw the signchart
var signchart = this;
if (this.mode === 'edit') {
this.captionelem.html('<span class="editablecaption mathquill-textbox">'+this.caption+'</span>').find('.editablecaption:not(.mathquill-rendered-math)').mathquill('textbox');
} else {
this.captionelem.html(this.caption.replace(/\$([^$]*)\$/g, '<span class="mathquill-embedded-latex">$1</span>')).find('.mathquill-embedded-latex:not(.mathquill-rendered-math)').mathquill();
}
var $thead = this.place.find('thead.pssc_head');
var $tbody = this.place.find('tbody.pssc_body');
$tbody.empty();
// Draw each function row.
for (var i = 0; i < this.rows.length; i++){
if (this.mode === 'view') {
this.viewRow($tbody, i);
} else {
this.editRow($tbody, i);
}
}
if (this.rows.length > 1){
// Draw the total row.
var $trow = $('<tr class="pssc_total"></tr>');
$trow.append('<td colspan="2" class="pssc_total"><span class="mathquill">'+this.total.func+'</span></td>');
for (var j = 0; j < this.roots.length; j++){
var thisundefined = (this.undefinedpoint[j] ? ' isundefined': '');
if (this.mode === 'edit') {
$trow.append('<td class="pssc_sign" sign="'+this.getTotalSign(j)+'" rootnum="'+j+'"><div class="pssc_totalwrapper"><a href="javascript:;" class="pssc_totalsign"></a><a href="javascript:;" class="pssc_totalundefined'+thisundefined+'"></a></div></td>');
} else {
$trow.append('<td class="pssc_sign" sign="'+this.getTotalSign(j)+'" rootnum="'+j+'"><div class="pssc_totalwrapper"><span class="pssc_totalsign"></span><span class="pssc_totalundefined'+thisundefined+'"></span></div></td>');
}
}
if (this.mode === 'edit') {
$trow.append('<td class="pssc_sign" sign="'+this.getTotalSign(this.roots.length)+'" rootnum="'+this.roots.length+'"><a href="javascript:;" class="pssc_totalsign"></a></td>');
} else {
$trow.append('<td class="pssc_sign" sign="'+this.getTotalSign(this.roots.length)+'" rootnum="'+this.roots.length+'"><span class="pssc_totalsign"></span></td>');
}
$tbody.append($trow);
// Function on total row is editable, if in edit-mode.
if (this.mode === 'edit'){
$tbody.find('tr.pssc_total td span.mathquill').addClass('mathquill-editable');
}
this.place.find('.mathquill-editable:not(.mathquill-rendered-math, .mathquill-textbox)').mathquill('editable');
this.place.find('.mathquill:not(.mathquill-rendered-math)').mathquill();
} else if (this.rows.length === 0){
// If there are no rows, show a symbol for empty table.
$tbody.append('<tr class="pssc_emptytable"><td>'+Pssignchart.strings.icons.emptytable+'</td></tr>');
}
if (this.rows.length > 0){
// Add intervals
var lefthandside = (this.rows.length === 1 ? this.rows[0].func : this.total.func);
if (this.mode === 'edit') {
var intervalhtml = '<td colspan="2"><div class="pssc_inequality"><a href="javascript:;" class="pssc_ineqlink"><span class="pssc_ineq">'+ lefthandside + this.getTotalRelation() +'0</span></a></div></td>';
for (var i = 0; i < this.roots.length; i++){
intervalhtml += '<td class="pssc_interval"><span><a href="javascript:;" class="pssc_intervalline" intervaltype="'
+this.getInterval(i)+'"></a><a href="javascript:;" class="pssc_rootpoint" pointtype="'
+this.getRootpoint(i)+'"></a></span></td>';
}
intervalhtml += '<td class="pssc_interval"><span><a href="javascript:;" class="pssc_intervalline" intervaltype="'
+this.getInterval(this.roots.length)+'"></a></span></td>';
} else {
var intervalhtml = '<td colspan="2"><div class="pssc_inequality"><span class="pssc_ineqlink"><span class="pssc_ineq">'+ lefthandside + this.getTotalRelation() +'0</span></span></div></td>';
for (var i = 0; i < this.roots.length; i++){
intervalhtml += '<td class="pssc_interval"><span><span class="pssc_intervalline" intervaltype="'
+this.getInterval(i)+'"></span><span class="pssc_rootpoint" pointtype="'
+this.getRootpoint(i)+'"></span></span></td>';
}
intervalhtml += '<td class="pssc_interval"><span><span class="pssc_intervalline" intervaltype="'
+this.getInterval(this.roots.length)+'"></span></span></td>';
}
this.place.find('table.pssc_table tbody.pssc_intervals tr').html(intervalhtml)
.find('.pssc_ineq').mathquill('embedded-latex');
this.place.find('.pssc_ineq > span.binary-operator').last().addClass('pssc_ineqrelation');
}
// Add labels for roots.
$thead.empty().append('<tr><td colspan="2"><div></div></td></tr>');
$thtr = $thead.find('tr');
for (var i = 0; i < this.roots.length; i++){
$thtr.append('<td class="pssc_headrootlabel"><div class="pssc_rootlabel"><span class="mathquill">'+this.roots[i].label+'</span></div></td>');
}
this.place.find('.mathquill:not(.mathquill-rendered-math)').mathquill();
// If in editmode, init all actions.
if (this.mode === 'edit'){
this.initEdit();
}
}
Pssignchart.prototype.viewRow = function($tbody, i){
// Add a row in view mode.
var $trow = $('<tr></tr>');
$trow.append('<td class="pssc_func"><span class="mathquill">'+this.rows[i].func
+'</span></td><td class="pssc_motivation" mot="'+this.getMotString(i)
+'"><span class="motshow"><span></span></span></td>');
// Draw each "slot" in a function row.
for (var j = 0, rowroot = 0; j < this.roots.length; j++){
var $tdata = $('<td class="pssc_sign" sign="'+this.getSign(i, rowroot)+'" rootnum="'+rowroot+'"><span class="pssc_sign_elem"></span></td>');
if (this.rows[i].isRoot(this.roots[j])){
$tdata.addClass('pssc_isroot');
rowroot++;
}
$trow.append($tdata);
}
$trow.append('<td class="pssc_sign" sign="'+this.getSign(i, rowroot)+'" rootnum="'+rowroot+'"><span class="pssc_sign_elem"></span></td>');
$tbody.append($trow);
}
Pssignchart.prototype.editRow = function($tbody, i){
// Add a row in edit mode
var $trow = $('<tr></tr>');
$trow.append('<td class="pssc_func"><span class="mathquill">'+this.rows[i].func
+'</span></td><td class="pssc_motivation" mot="'+this.getMotString(i)
+'"><a href="javascript:;" class="motshow"><span></span></a></td>');
// Draw each "slot" in a function row.
for (var j = 0, rowroot = 0; j < this.roots.length; j++){
var $tdata = $('<td class="pssc_sign" sign="'+this.getSign(i, rowroot)+'" rootnum="'+rowroot+'"><a href="javascript:;"></a></td>');
if (this.rows[i].isRoot(this.roots[j])){
$tdata.addClass('pssc_isroot');
rowroot++;
}
$trow.append($tdata);
}
$trow.append('<td class="pssc_sign" sign="'+this.getSign(i, rowroot)+'" rootnum="'+rowroot+'"><a href="javascript:;"></a></td>');
$tbody.append($trow);
}
Pssignchart.prototype.initEdit = function(){
// Init editing events of the signchart
var signchart = this;
var $tbody = this.place.find('tbody.pssc_body');
// Init remove row.
$tbody.find('td.pssc_func')
.prepend('<a href="javascript:;" class="pssc_removerow_button pssc_bggrad"><span class="pssc_text">-</span><span class="pssc_icon"></span></a>')
.find('a.pssc_removerow_button')
.click(function(){
var $thisbutton = $(this);
var $thisfunc = $thisbutton.parents('td.pssc_func');
var $allfunc = $thisfunc.parents('tbody').find('td.pssc_func');
var index = $allfunc.index($thisfunc);
signchart.removeFunc(index);
signchart.place.find('.pssc_toolbar a.removerow.isopen').click().click();
if (signchart.rows.length === 0){
signchart.place.find('tbody.pssc_intervals tr').empty();
}
});
// Init clicks for motivations.
$tbody.find('td.pssc_motivation a').click(function(){
var $motlink = $(this);
if (!$motlink.hasClass('isopen')){
$motlink.addClass('isopen');
var $tdmot = $motlink.parent('td');
var rownum = $tdmot.parents('tbody').find('tr').index($tdmot.parents('tr').eq(0));
signchart.changeMotivation($tdmot, rownum);
}
});
// Init sign clicks for plus, minus and none.
$tbody.find('td.pssc_sign').click(function(){
var $tdsign = $(this);
$tdsign.trigger('pssc_signchange');
});
// Init sign clicks for plus, minus and none.
$tbody.find('td.pssc_sign').bind('pssc_signchange', function(){
var $td = $(this);
var rownum = $td.parents('tbody').find('tr').index($td.parents('tr').eq(0));
var rootnum = parseInt($td.attr('rootnum'));
var istotal = $td.parents('tr').eq(0).hasClass('pssc_total');
var sign = $td.attr('sign');
var newsign;
switch (sign){
case 'plus':
newsign = 'minus';
break;
case 'minus':
newsign = '';
break;
case '':
newsign = 'plus';
break;
default:
newsign = '';
}
$td.parent('tr').find('td[rootnum="'+rootnum+'"]').attr('sign', newsign);
if (istotal){
signchart.setTotalSign(rootnum, newsign);
} else {
signchart.setSign(rownum, rootnum, newsign);
}
});
// Init focus highlights for signs.
$tbody.find('td.pssc_sign a.pssc_totalsign').focus(function(){
$(this).parent().addClass('focushere');
}).blur(function(){
$(this).parent().removeClass('focushere');
});
// Init clicks for undefined points.
$tbody.find('td.pssc_sign a.pssc_totalundefined').click(function(){
var $thistd = $(this).parents('td');
var index = $thistd.parent('tr').find('td').index($thistd) -1;
var height=$thistd.eq(0).height();
$(this).toggleClass('isundefined').css({'height': height + 'px', 'top': -9-(height/2)+'px'});
signchart.setUndef(index ,$(this).hasClass('isundefined'));
return false;
});
// Init clicks for rootpoints
this.place.find('tbody.pssc_intervals a.pssc_rootpoint').click(function(){
var $td = $(this).parents('td').eq(0);
var $alltds = $td.parents('tr').eq(0).children('td');
var rootindex = $alltds.index($td) - 1;
var pointtype = $(this).attr('pointtype');
switch (pointtype){
case 'open':
$(this).attr('pointtype','closed');
signchart.setRootpoint(rootindex, 'closed');
break;
case 'closed':
$(this).attr('pointtype','');
signchart.setRootpoint(rootindex, '');
break;
default:
$(this).attr('pointtype','open');
signchart.setRootpoint(rootindex, 'open');
}
});
// Init clicks for intervallines
this.place.find('tbody.pssc_intervals a.pssc_intervalline').click(function(){
var $td = $(this).parents('td').eq(0);
var $alltds = $td.parents('tr').eq(0).children('td');
var intindex = $alltds.index($td) - 1;
var intervaltype = $(this).attr('intervaltype');
switch (intervaltype){
case 'inside':
$(this).attr('intervaltype','');
signchart.setInterval(intindex, '');
break;
default:
$(this).attr('intervaltype','inside');
signchart.setInterval(intindex, 'inside');
}
});
// Init focusout for function on total row.
this.place.find('tbody.pssc_body tr.pssc_total td.pssc_total span.mathquill-editable').focusout(function(){
var latex = $(this).mathquill('latex');
signchart.total.func = latex;
signchart.place.find('tbody.pssc_intervals a.pssc_ineqlink')
.html('<span class="pssc_ineq">'+latex + signchart.getTotalRelation() + '0</span>')
.find('.pssc_ineq').mathquill('embedded-latex');
signchart.place.find('.pssc_ineq > span.binary-operator').last().addClass('pssc_ineqrelation');
signchart.changed();
});
// Init focusout for caption.
this.captionelem.find('.mathquill-textbox').bind('focusout', function(e){
var cap = $(this);
var latex = cap.mathquill('latex');
if (signchart.caption !== latex) {
signchart.caption = latex;
signchart.changed();
}
});
// Init click to change relation of inequality.
this.place.find('tbody.pssc_intervals a.pssc_ineqlink').click(function(){
var lefthandside = (signchart.rows.length === 1 ? signchart.rows[0].func : signchart.total.func);
signchart.nextTotalRelation();
$(this).html('<span class="pssc_ineq">'+lefthandside + signchart.getTotalRelation() + '0</span>')
.find('.pssc_ineq').mathquill('embedded-latex');
signchart.place.find('.pssc_ineq > span.binary-operator').last().addClass('pssc_ineqrelation');
signchart.changed();
});
}
Pssignchart.prototype.showEdit = function(){
// Init actions for adding and removing functions.
var signchart = this;
this.place.prepend('<div class="pssc_toolbarwrapper"></div>');
this.toolbar = this.place.find('.pssc_toolbarwrapper');
signchart.toolbar.append('<div class="pssc_addrowbox pssc_bggrad">'
+'<span class="pssc_newfunc_title">f:</span><span class="mathquill-editable pssc_newfunc"></span>'
+'<div class="pssc_newroots" roots="0"><a href="javascript:;" class="pssc_newroots_title pssc_bggrad">0</a><span class="mathquill-editable pssc_newroot1"></span><span class="mathquill-editable pssc_newroot2"></span></div><a href="javascript:;" class="pssc_addfuncbutton"><span class="pssc_text">+</span><span class="pssc_icon"></span></a></div>');
signchart.toolbar.find('.pssc_addrowbox')
.find('.mathquill-editable:not(.mathquill-rendered-math)')
.mathquill('editable').eq(0).focus();
signchart.toolbar.find('.pssc_addrowbox .pssc_newroots_title').click(function(){
var $newroots = $(this).parents('.pssc_newroots');
var amount = parseInt($newroots.attr('roots'));
amount = (amount + 1) % 3;
$newroots.attr('roots', amount);
$(this).html(amount);
});
signchart.toolbar.find('.pssc_addrowbox .mathquill-editable').bind('keyup.pssignchart',function(e){
var key = e.keyCode;
switch (key){
case 13:
$(this).parents('.pssc_addrowbox').find('a.pssc_addfuncbutton').click();
break;
default:
break;
}
});
signchart.toolbar.find('a.pssc_addfuncbutton').click(function(){
var numofroots = parseInt($(this).parent().find('.pssc_newroots').attr('roots'));
var newfunc = signchart.toolbar.find('.pssc_newfunc').mathquill('latex');
var newroot = [];
var newrootval = [];
var rootsok = true;
var rootlist = [];
for (var i = 0; i < numofroots; i++){
newroot[i] = signchart.toolbar.find('.pssc_newroot'+(i+1)).mathquill('latex');
try {
newrootval[i] = latexeval(newroot[i]);
rootsok = rootsok && (typeof(newrootval[i]) === 'number');
rootlist.push({label: newroot[i], value: newrootval[i]});
} catch (err){
if (err === 'Invalidexpression'){
signchart.toolbar.find('.pssc_newroot'+(i+1)).addClass('inputerror').focus().delay(2000).queue(function(){$(this).removeClass('inputerror');$(this).dequeue();});
rootsok = false;
}
}
}
if (rootsok){
signchart.place.trigger('add', {func: newfunc, roots: rootlist});
signchart.toolbar.find('.pssc_newfunc').mathquill('latex','').focus();
signchart.toolbar.find('.pssc_newroot1').mathquill('latex','');
signchart.toolbar.find('.pssc_newroot2').mathquill('latex','');
}
});
signchart.place.find('td.pssc_func')
.prepend('<a href="javascript:;" class="pssc_removerow_button pssc_bggrad"><span></span></a>')
.find('a.pssc_removerow_button')
.click(function(){
var $thisbutton = $(this);
var $thisfunc = $thisbutton.parents('td.pssc_func');
var $allfunc = $thisfunc.parents('tbody').find('td.pssc_func');
var index = $allfunc.index($thisfunc);
signchart.removeFunc(index);
signchart.place.find('.pssc_toolbar a.removerow.isopen').click().click();
if (signchart.rows.length === 0){
signchart.place.find('tbody.pssc_intervals tr').remove();
}
});
}
Pssignchart.prototype.isInRoots = function(root){
result = false;
for (var i = 0; i < this.roots.length; i++){
if (this.roots[i].isEqual(root)){
result = true;
break;
}
}
return result;
}
Pssignchart.prototype.changeMotivation = function($tdelem, rownum){
var signchart = this;
var menuhtml = '<div class="motivationselectwrapper"><ul class="motivationselector">';
for (var i = 0; i < Pssignchart.mot.length; i++){
menuhtml += '<li><a href="javascript:;" mot="'+Pssignchart.mot[i]+'"><span></span></a></li>';
}
menuhtml += '</ul></div>';
$tdelem.append(menuhtml).find('.motivationselectwrapper ul.motivationselector').hide().fadeIn(600);
$tdelem.find('ul.motivationselector a').click(function(){
var newmot = $(this).attr('mot');
$tdelem.attr('mot', newmot);
signchart.setMotString(rownum, newmot);
$(this).parents('.motivationselectwrapper').find('ul.motivationselector').fadeOut(600, function(){$(this).remove()});
$tdelem.find('a.motshow').removeClass('isopen');
});
}
Pssignchart.prototype.addFunc = function(options, nodraw){
// Add a new function on a new row.
options = $.extend({
func: '',
roots: [],
signs: []
}, options);
for (var i = 0; i < options.roots.length; i++){
var root = options.roots[i];
if (typeof(options.roots[i]) === 'number'){
root = new PsscRoot({label: ''+options.roots[i], value: options.roots[i]});
} else if (typeof(options.roots[i]) === 'object'
&& typeof(options.roots[i].label) === 'string'
&& typeof(options.roots[i].value) === 'number'){
root = new PsscRoot({label: options.roots[i].label, value: options.roots[i].value});
}
options.roots[i] = root;
if (!this.isInRoots(root)){
this.roots.push(root);
};
}
for (var i = 0; i < this.roots.length; i++){
this.undefinedpoint[i] = false;
this.rootpoints[i] = '';
this.intervals[i] = '';
this.total.signs[i] = '';
}
this.intervals[this.roots.length] = '';
this.total.signs[this.roots.length] = '';
var row = new PsscRow(options);
this.rows.push(row);
this.roots.sort(function(a,b){return (a.value < b.value ? -1 : 1)});
if (!nodraw){
this.draw();
}
this.changed();
return this;
}
Pssignchart.prototype.removeFunc = function(index){
// Remove a function.
this.rows.splice(index, 1);
this.refreshRoots();
// Empty total and intervals
this.undefinedpoint = [];
this.rootpoints = [];
this.intervals = [];
this.total.signs = [];
for (var i = 0; i < this.roots.length; i++){
this.undefinedpoint[i] = false;
this.rootpoints[i] = '';
this.intervals[i] = '';
this.total.signs[i] = '';
}
this.intervals[this.roots.length] = '';
this.total.signs[this.roots.length] = '';
this.draw();
this.changed();
}
Pssignchart.prototype.refreshRoots = function(){
// Rebuild roots-list.
this.roots = [];
for (var i = 0; i < this.rows.length; i++){
for (var j = 0; j < this.rows[i].roots.length; j++){
if (!this.isInRoots(this.rows[i].roots[j])){
this.roots.push(this.rows[i].roots[j]);
}
}
}
this.roots.sort(function(a,b){return (a.value < b.value ? -1 : 1)});
}
Pssignchart.prototype.addTotal = function(options, nodraw){
options.func = options.func || '';
var emptysigns = [];
for (var i = 0; i < this.roots.length; i++){
emptysigns.push('');
}
options.signs = options.signs || this.total.signs || emptysigns;
options.relation = options.relation || this.total.relation || '\\lt';
this.total = {func: options.func, signs: options.signs, relation: options.relation};
if (!nodraw){
this.draw();
}
this.changed();
return this;
}
Pssignchart.prototype.setMot = function(row, mot){
this.rows[row].setMotivation(mot);
}
Pssignchart.prototype.getMot = function(row){
return this.rows[row].getMotivation() || 0;
}
Pssignchart.prototype.setMotString = function(row, motstring){
var mot = Pssignchart.mot.indexOf(motstring);
mot = (mot > -1) ? mot : 0;
this.setMot(row, mot);
this.changed();
}
Pssignchart.prototype.getMotString = function(row){
return Pssignchart.mot[this.getMot(row)];
}
Pssignchart.prototype.setSign = function(row, col, sign){
if (sign !== 'plus' && sign !== 'minus'){
return false;
}
this.rows[row].setSign(col, sign);
this.changed();
}
Pssignchart.prototype.getSign = function(row, col){
return this.rows[row].getSign(col) || '';
}
Pssignchart.prototype.setTotalSign = function(col, sign){
this.total.signs[col] = sign;
this.changed();
}
Pssignchart.prototype.getTotalSign = function(col){
return this.total.signs[col] || '';
}
Pssignchart.prototype.setTotalRelation = function(relation){
this.total.relation = relation;
this.changed();
}
Pssignchart.prototype.getTotalRelation = function(){
return this.total.relation || '\\lt';
}
Pssignchart.prototype.nextTotalRelation = function(){
var relations = ['\\lt','\\gt','\\leq','\\geq'];
this.total.relation = relations[(relations.indexOf(this.total.relation) + 1) % relations.length];
this.changed();
}
Pssignchart.prototype.setInterval = function(n, onoff){
onoff = (onoff ? 'inside':'');
if (n < 0 || n > this.roots.length){
return false;
}
this.intervals[n] = onoff;
this.changed();
return this.intervals[n];
}
Pssignchart.prototype.getInterval = function(n){
return this.intervals[n] || '';
}
Pssignchart.prototype.setRootpoint = function(n, onoff){
if (n < 0 || n > this.roots.length -1 || (onoff !== 'closed' && onoff !== 'open' && onoff !== '')){
return false;
}
this.rootpoints[n] = onoff;
this.changed();
return this.rootpoints[n];
}
Pssignchart.prototype.getRootpoint = function(n){
return this.rootpoints[n] || '';
}
Pssignchart.prototype.setUndef = function(index, onoff){
if (index < 0 || index > this.roots.length -1){
return false;
}
this.undefinedpoint[index] = onoff;
this.changed();
return this.undefinedpoint[index];
}
Pssignchart.prototype.getUndef = function(index){
return this.undefinedpoint[index] || '';
}
Pssignchart.prototype.getData = function(options){
var data = {rows: [], total: {func: "", signs: [], relation: '\\lt'}, intervals: [], rootpoints: [], undefinedpoint: [], caption: this.caption};
for (var i=0; i<this.rows.length; i++){
data.rows.push(this.rows[i].getData());
}
data.total.func = this.total.func;
data.total.signs = this.total.signs;
data.total.relation = this.total.relation;
data.intervals = this.intervals.slice(0);
data.rootpoints = this.rootpoints.slice(0);
data.undefinedpoint = this.undefinedpoint.slice(0);
options.result = data;
}
Pssignchart.prototype.setData = function(options){
this.empty();
this.caption = options.caption || '';
for (var i = 0; i < options.rows.length; i++){
this.addFunc(options.rows[i], true);
}
this.addTotal(options.total, true);
this.intervals = options.intervals.slice(0);
this.rootpoints = options.rootpoints.slice(0);
this.undefinedpoint = options.undefinedpoint.slice(0);
this.draw();
this.changed();
}
Pssignchart.prototype.empty = function(){
this.rows = [];
this.roots = [];
this.total = {func: '', signs: ['']};
this.intervals = [];
this.rootpoints = [];
this.caption = '';
this.draw();
this.changed();
}
Pssignchart.prototype.changed = function(){
this.place.trigger('pssc_changed');
}
Pssignchart.prototype.initEvents = function(){
var schart = this;
this.place.bind('add', function(e, options){
schart.addFunc(options);
});
this.place.bind('total', function(e, options){
schart.addTotal(options);
});
this.place.bind('setsign', function(e, options){
schart.setSign(options.row, options.col, options.sign);
schart.draw();
});
this.place.bind('settotsign', function(e, options){
schart.setTotalSign(options.col, options.sign);
schart.draw();
});
this.place.bind('setinterval', function(e, options){
schart.setInterval(options.col, options.onoff);
schart.draw();
});
this.place.bind('setrootpoint', function(e, options){
schart.setRootpoint(options.col, options.onoff);
schart.draw();
});
this.place.bind('setundef', function(e, options){
schart.setUndef(options.col, options.onoff);
schart.draw();
});
this.place.bind('setmot', function(e, options){
schart.setMotString(options.row, options.mot);
schart.draw();
});
this.place.bind('get', function(e, options){
return schart.getData(options);
});
this.place.bind('set', function(e, options){
schart.setData(options);
schart.draw();
})
this.place.bind('empty', function(e, options){
schart.empty();
})
return this;
}
Pssignchart.mot = [
'',
'linear-asc',
'linear-desc',
'parab-up-0',
'parab-up-1',
'parab-up-2',
'parab-down-0',
'parab-down-1',
'parab-down-2'
]
Pssignchart.strings = {
icons: {
emptytable: '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="60" height="60" viewbox="0 0 30 30"><path fill="#ccc" stroke="white" d="M5 15 a10 10 0 0 0 20 0 a10 10 0 0 0 -20 0z M10 20 a7 7 0 0 1 6 -12z M20 10 a7 7 0 0 1 -6 12z" /></svg>'
},
style:[
'.pssc_default {min-height: 2em; background-color: white; padding: 5px 15px 15px 15px; border: 1px solid black; border-radius: 15px; box-shadow: 5px 5px 5px rgba(0,0,0,0.5); margin: 1em 0; text-align: center;}',
'.pssc_default {background: rgb(254,255,232); /* Old browsers */ background: -moz-linear-gradient(top, rgba(254,255,232,1) 0%, rgba(214,219,191,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,255,232,1)), color-stop(100%,rgba(214,219,191,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(254,255,232,1) 0%,rgba(214,219,191,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#feffe8", endColorstr="#d6dbbf",GradientType=0 ); /* IE6-9 */}',
'.pssignchart .pssc_tablewrapper {clear: both; text-align: center; display: block;}',
'.pssignchart a:hover {background-color: transparent;}',
'.pssc_default table.pssc_table {border-collapse: collapse; margin: 0.2em auto; border: none; display: inline-block; text-align: left;}',
'.pssc_default table.pssc_table caption {caption-side: bottom; text-align: center; margin: 1em 0 0 0;}',
'.pssc_default table.pssc_table caption span.mathquill-textbox {display: block; border: none;}',
'.pssignchartwrapper {text-align: center;}',
'.pssignchart {position: relative; display: inline-block; text-align: left; min-height: 70px; padding: 0.5em;}',
'.pssignchart.editmode {margin-bottom: 2em;}',
'.pssc_default table.pssc_table tbody.pssc_body {border: 1px solid black; min-width: 10em;}',
'table.pssc_table tr:nth-child(even) td {background-color: #eef;/*#dfb;*/}',
'table.pssc_table tr:nth-child(odd) td {background-color: white;}',
'table.pssc_table tr.pssc_total {border-top: 4px solid black;}',
'.pssc_tablewrapper {margin: 0 auto; position: relative;}',
'table.pssc_table .pssc_head tr td {color: black; background-color: transparent; padding-top: 0.7em;}',
'table.pssc_table .pssc_head td div {min-height: 1em;}',
'td.pssc_headrootlabel {text-align: right;}',
'td.pssc_headrootlabel .pssc_rootlabel {text-align: left; display: inline-block;}',
'.pssc_rootlabel {position: relative; overflow: visible; text-align: center; white-space: nowrap; padding-bottom: 0.5em;}',
'.pssc_rootlabel > span.mathquill {display: inline-block; position: relative; right: -50%; margin-top: -1em; vertical-align: bottom; white-space: nowrap;}',
'table.pssc_table .pssc_body tr.pssc_emptytable td {width: 15em;}',
'table.pssc_table .pssc_body tr.pssc_emptytable td svg {display: block; width: 60px; margin: 0.5em auto;}',
'table.pssc_table .pssc_body td.pssc_isroot {border-right: 3px solid black;}',
'table.pssc_table .pssc_body td {min-width: 3em; border-right: 1px dotted black; padding: 0;}',
'table.pssc_table .pssc_body td.pssc_func {padding: 0 1em; border-right: none;}',
'.editmode table.pssc_table .pssc_body td.pssc_motivation {padding: 0 1em; border-right: 1px solid black; cursor: pointer; padding: 0;}',
'table.pssc_table .pssc_body td.pssc_motivation a span, table.pssc_table .pssc_body td.pssc_motivation span span {width: 30px; height: 20px; display: block; margin: 0 auto;}',
'table.pssc_table .pssc_body td.pssc_motivation a {text-align: center; display: block; border: 1px solid #777; border-radius: 4px; margin: 0;}',
'table.pssc_table .pssc_body td.pssc_motivation > span {text-align: center; display: block; margin: 0;}',
'table.pssc_table .pssc_body td.pssc_motivation a.motshow {margin: 3px;}',
'.pssc_default, table.pssc_table td.pssc_motivation a, .pssignchart .pssc_toolbar li a, .pssignchart .pssc_addfuncbutton, .pssc_bggrad {',
'background: rgb(255,255,255); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(255,255,255,1) 0%, rgba(246,246,246,1) 47%, rgba(237,237,237,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,1)), color-stop(47%,rgba(246,246,246,1)), color-stop(100%,rgba(237,237,237,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(255,255,255,1) 0%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#ffffff", endColorstr="#ededed",GradientType=0 ); /* IE6-9 */}',
'table.pssc_table td.pssc_total {padding: 0 1em; border-right: 1px solid black;}',
'table.pssc_table td.pssc_motivation[mot="linear-asc"] .motshow span, ul.motivationselector a[mot="linear-asc"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEGSURBVEiJxdWxSoMxFMXx39XOYl3EQcFFO+ju/E3dFXwAn0foIgg+gVBwcPcl2urg4Obi3EnwOhSltNjaNp8euBDITf7knIREZvoPrdW1cURUEXH3Y0NmFi9UeEM1YK/H7lRPndDM1Oeyz9VkX5TMOCIq3OK8xzMugnbQwP06N4eZrxTMeByamQ9oBodoJptJ64Ot7wV12DteAzo9rotnPAuamZ44eOSoKHgedFYFTtBeItZ9nKGLlwXXdpe9XKtAR/pLe5fOuBQ0MzW+Th7hGKdjZryjk2k4mp96pyupMTbeQWsCvIFhaSjmW62gvb/OuC7oTHCd0Myc+UlsF810QkW/xUX0CTXVXBQFUC9+AAAAAElFTkSuQmCC); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="linear-desc"] .motshow span, ul.motivationselector a[mot="linear-desc"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAEVSURBVEiJxZTBSgJRFIa/X32CwGgTYds2ghAtYza5LBCkHqlV7dq3EEPoDcw3EIxp61patve46CZqTjpzj/nDYeDeM3xz///OkZmxD5WyNiTdSkr+DTyUqh/SATABujuDm9lSpXCfwmOIIAE+gWS1L7b0k/FIOizDncGNoGLwUoLnM6gDXaBtZn2vA8+tLsMJcKXv57GgOYXTAGvjbfsaqx/e4Wl1HWfbfy2MoJHC+dpmR3j+F5zgAi6AZs6EakAL6AHjAgn3MgfIBo0DtBU+Ir+icoqwPf52FoTPB0iMwv+9NGQkjoDrhbYp0DHjK9rqv04Odgn2BjYI1Qeru1ld1HZXcB64O3hb+E7AC/DXrH2XW11EM/myp6tY/ecvAAAAAElFTkSuQmCC); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-up-0"] .motshow span, ul.motivationselector a[mot="parab-up-0"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFjSURBVEiJ7dWxS1VhGMfxz3NRN9FyCJrEhis1OUS4SbvQFCStgRg4NPg3tDo41dDiINHQ2n9QLXFRcalREY0QGqOn5RXict/j8RbexQfOcJ7f8/v+eM8573kjM42iOjUhIlYjYnxYcESMR8SNSwfjKZZqYi+iexAx0+Bfwvthgt9ipSaOsfGbFw3+FbyriVF7xxExha+4l5nH5/1eRLfDk+ARfgYfOmzNZ37/y3sLe7iTmWeD+NUVF8M21voMM0EXU7iZzP9ius++hu1a6HlA9cIcjjDZr+3yZpeXAzyTxTPXyG4SC2gTO/39PRZ6A+DYweaF3BbBE/iE9Raz62V24p+DC3AWx1hsmFksM7OtmG2GCngZp3iu7IbSj9I7xXJbXnU7DaqIuItX5aP7XNr38Q3PMnO/NWuYf3VE3MaDcvsxMw8vzRjVIRF4iMdXnPt6DCf4csXBP0b2qJtOp+vg/1p/AHb4s9JeAxr4AAAAAElFTkSuQmCC); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-up-1"] .motshow span, ul.motivationselector a[mot="parab-up-1"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAF6SURBVEiJ7dSxalRREAbgb5YkXQgpJKJNClGLpBXT2YgWbq1EbUOMkAew8gUs0lpYiClERUQLC8Fe0pi9m7yBKAlI8AHGYk90uZtdblZQhAzc4vzzz/+fc2buicz0L6I1LBERqxExOa5wRExGxOyxjXEHV8Y1LrVvxjF+geU/MF7Gq6HZzDzywwz2MTeMM6J2rtTODOMMnHgn4nYVsZqZB9jE2hinXcNmZh5UETeqiAd1woBxshhcLssNrETEdFPHwl0ptVosBJcGeIe/UzfiGt7XNtFe5CpOZ+bNhsbP8XWbpy22anp3FzKf9RZ9977L+YrHHV5/5kL2bmQKn7DeoLfrhTuVmbqcq3hU8WGbix+Z+MWtF3e41+FhTXAe37A0wnSpcOb78YpbXTYG+EcKlRbUhNt6k3pfXx5RsH20h+i16ljoDdL1Jv3DqbKBWXwp2Bl8x1vsNdR5OdGQeBh7eIJpnC3YO/w4ps7vqf7bMerJPDE+Mf4/jX8CUIo9ubKExnoAAAAASUVORK5CYII=); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-up-2"] .motshow span, ul.motivationselector a[mot="parab-up-2"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHWSURBVEiJxZQ/SxxhEMZ/z+ZW8g1SiYqcf3KNiRIFGwMXTGdxmMoyxFLEPl0+hFXSJ0XaAy2sRLnDI1nvDlQk9vYhyk2Km1sXkvV2F8GBgX1nnnmemXmXV2bGY1iQlpD0QVKpKLGkUNL7VICZxf4TFgbfQAuYT+bzODAPnAzOp/AqmY8njqRRwVFbGvFQA1goOrHXNuMB4bAjlQfnEkBb2gxg1vqr/9iRGi68COwWFF4EjtvSeg8qgqAHW22p8dzsS/BVegJMGkx6Z1M9mAL2gTcFRfHafYMJwbRzTxjMIgXxzjswHoFdwtPEPV0AlQL3WwEukrEI7AfM/HPHM3AleDdu9jvRdR1YLTDtqtfGJljvwlkcGNL5GlAvMHEdWLsPU5K0BLxN6XwEWJH0CbjJOG0IrABNSS9SMN9SHxC3P8A58DKjKI4999p0y7C2OeAXEGbAho6dG4Yd+iSaWUtSBGwAnyWeAa8TkFvguxm3jonMrDV0Lxl/lmWgCwRgNbBWwptglX6OLrCciTPHn3oA1O7J14CDzHw5hKvAFTD2n9yY56oPLuwC2/QfgXIiVvbYdi6uPGAX2gGugWP3a2AnL4+cLJdJCn31AHtmlvVxueMoIvwQ9hchhu86AOETqAAAAABJRU5ErkJggg==); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-down-0"] .motshow span, ul.motivationselector a[mot="parab-down-0"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAErSURBVEiJ5dQxSoNBEIbhZ0ViqYUQsQpWkgso5gI2gqBga2lnk4OkzgUsYhNI4QUUTGVpZSnENAF7xyIbCGL++IdoCge22Nlv5mVnZzZFhFXY2kqo/xKccIjjP+beru7Gq+rq9UWCUkq7OMjbx4h4LZ0kIn68UMc9BrjLa5B99VK5SkBPMMSV/ETZn7JviJOlglHDGxoFmkbW1JYCRgV9NH+gbWZtZRngFrolnqSL1jxd4TillPbwgP2IGI19dnA6JfvATYT3HLOFZxxFxMus3PPG6RrtCTTbPi6Mm2oC7uMJImKUUmrn2OuZmQtKtmncqdUyY5Jjqzl2c5am6Mu8RC8iBnOq8t1lBujlHN9aEfgcnbLQKevgbOZpQbmusFG2zF/GcHuhrv5N+wSM50No4tDxQgAAAABJRU5ErkJggg==); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-down-1"] .motshow span, ul.motivationselector a[mot="parab-down-1"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAE/SURBVEiJ7dS/SlxREMfxzwmynSwIsoWFaxN8BGFfQCGL+UMwnZZ2NltbJI2tz2BhsWmCgk1eIFYp06WKuFkQor2TYs/iRbzXe1GxceDCZc5v5nuG+XFSRHiOePUs1BfwC/gpI2EFqw3rZrGQ///gqmH915mGBfPoYw7nOfcGFzjCuHaniKj1ZeAY20iFfMq5Mfq1+9WEdvEXvQpNL2u6jwJGC6cY1NAOsrZ1nzZN3+qUdPCusIVrHJK+YCki1uusLqX0Db+JPby93S9iYsSiuV5jo7h+Ds7wCct1oDk28YuTH6xtmHhgCj7FT9xMXHL7ffyLiN0GYCmlz2hHxE6pqGJfbROnduo6tVDbybXtMk3Vy7WF44gYNZk2DzPCce5xZ1SBP2DYFFqIIT6WHVa9XO9x+QDwdyyWHVaa6ynjP4T7ZWdT7KhuAAAAAElFTkSuQmCC); background-position: center center; background-repeat: no-repeat;}',
'table.pssc_table td.pssc_motivation[mot="parab-down-2"] .motshow span, ul.motivationselector a[mot="parab-down-2"] span ',
'{background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAUCAYAAACaq43EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGfSURBVEiJxdU/a1RBFAXw340LIX8gnZhCyCdQg41YyK4WWqWySQrzPezFxsIqCOkklSwpTBVIKsGk2EJ239rYBAS3lQW1cyx2Amt03+7bLHpgijf3nnPnzNyZFykl/wO1aUgRcR2P82czpfS5qsZcxYIREbtoYz2PdkTsRkRUqpxSmnhgB++w9J6FN1zBUp7bqaRVoegmPmAlpaTgeYenObaSY5szLYxAB/UWix3qBW8Lmh+5l53Xc07MsvAGTlJKumwU9Lp8L/hW8KXD3Zx3go1ZFj69KNjhVZeXf1ng6SSaY7s6Ih5gGQfD83Mc/+ToQvoBljOnXBd38Kgk54lB47THiWXcwC28LslpjnO8iFUUExaVc1czdzTGnO0W9qvcz8zbx9ZlzvghDiu4Pcdh5lZ3bHD+PaxN4Xgtc0fe6VqEeTwz6NxzHOMT+imls6p2U0pnEdHHzQhXcX8o/BUvatlZ3+9/qh9o+PO6VMFR1ujh2tD8AubLtmsP21W3eYi/jb1pmmsdrUs4buH2yGjJihsmfPBLmrMxKh456Z/jF3i7xrFI8axPAAAAAElFTkSuQmCC); background-position: center center; background-repeat: no-repeat;}',
'.motivationselectwrapper {position: relative;}',
'.motivationselectwrapper ul.motivationselector {position: absolute; top: -25px; left: -6px; list-style: none; margin: 0; padding: 2px; width: 102px; background-color: #eee;',
'border: 1px solid #777; border-radius: 4px; box-shadow: 4px 4px 4px rgba(0,0,0,0.5); z-index: 10;}',
'.motivationselectwrapper ul.motivationselector li {display: inline-block; margin: 1px; padding: 0; vertical-align: top;}',
'.motivationselectwrapper ul.motivationselector li a {width: 30px; height: 20px; margin: 0; padding: 0; display: block;}',
'table.pssc_table td.pssc_sign {cursor: default; text-align: center; min-width: 50px; width: 50px;}',
'.editmode table.pssc_table td.pssc_sign {cursor: pointer; text-align: center; min-width: 50px; width: 50px;}',
'table.pssc_table td.pssc_sign[sign=""]:before {content: "\\0000a0";}',
'table.pssc_table td.pssc_sign[sign="plus"]:before {content: "+"; font-weight: bold; display: block; text-align: center; color: white; text-shadow: 0 0 1px black; margin: 0 7px;}',
'table.pssc_table td.pssc_sign[sign="plus"] {background: rgb(248,80,50); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(248,80,50,1) 0%, rgba(241,111,92,1) 50%, rgba(246,41,12,1) 51%, rgba(240,47,23,1) 71%, rgba(231,56,39,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(248,80,50,1)), color-stop(50%,rgba(241,111,92,1)), color-stop(51%,rgba(246,41,12,1)), color-stop(71%,rgba(240,47,23,1)), color-stop(100%,rgba(231,56,39,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(248,80,50,1) 0%,rgba(241,111,92,1) 50%,rgba(246,41,12,1) 51%,rgba(240,47,23,1) 71%,rgba(231,56,39,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(248,80,50,1) 0%,rgba(241,111,92,1) 50%,rgba(246,41,12,1) 51%,rgba(240,47,23,1) 71%,rgba(231,56,39,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(248,80,50,1) 0%,rgba(241,111,92,1) 50%,rgba(246,41,12,1) 51%,rgba(240,47,23,1) 71%,rgba(231,56,39,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(248,80,50,1) 0%,rgba(241,111,92,1) 50%,rgba(246,41,12,1) 51%,rgba(240,47,23,1) 71%,rgba(231,56,39,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#f85032", endColorstr="#e73827",GradientType=0 ); /* IE6-9 */}',
'table.pssc_table td.pssc_sign[sign="minus"]:before {content: "\u2014"; font-weight: bold; display: block; text-align: center; color: white; text-shadow: 0 0 1px black; margin: 0 7px;}',
'table.pssc_table td.pssc_sign[sign="minus"] {background: rgb(183,222,237); /* Old browsers */',
'background: -moz-linear-gradient(top, rgba(183,222,237,1) 0%, rgba(113,206,239,1) 50%, rgba(33,180,226,1) 51%, rgba(183,222,237,1) 100%); /* FF3.6+ */',
'background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(183,222,237,1)), color-stop(50%,rgba(113,206,239,1)), color-stop(51%,rgba(33,180,226,1)), color-stop(100%,rgba(183,222,237,1))); /* Chrome,Safari4+ */',
'background: -webkit-linear-gradient(top, rgba(183,222,237,1) 0%,rgba(113,206,239,1) 50%,rgba(33,180,226,1) 51%,rgba(183,222,237,1) 100%); /* Chrome10+,Safari5.1+ */',
'background: -o-linear-gradient(top, rgba(183,222,237,1) 0%,rgba(113,206,239,1) 50%,rgba(33,180,226,1) 51%,rgba(183,222,237,1) 100%); /* Opera 11.10+ */',
'background: -ms-linear-gradient(top, rgba(183,222,237,1) 0%,rgba(113,206,239,1) 50%,rgba(33,180,226,1) 51%,rgba(183,222,237,1) 100%); /* IE10+ */',
'background: linear-gradient(to bottom, rgba(183,222,237,1) 0%,rgba(113,206,239,1) 50%,rgba(33,180,226,1) 51%,rgba(183,222,237,1) 100%); /* W3C */',
'filter: progid:DXImageTransform.Microsoft.gradient( startColorstr="#b7deed", endColorstr="#b7deed",GradientType=0 ); /* IE6-9 */}',
'table.pssc_table .focushere {box-shadow: 2px 2px 1px green, -2px -2px 1px green, 2px -2px 1px green, -2px 2px 1px gree;}',
'.pssc_default table.pssc_table tbody.pssc_intervals {border: none; background-color: transparent;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td {border: none; background-color: transparent; height: 1em;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval {border-bottom: 1px dotted #777; vertical-align: bottom;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span {display: block; margin: 0; padding: 0; position: relative;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span .pssc_rootpoint {display: inline-block; position: absolute; width: 8px; height: 8px; right: -5px; bottom: -6px; border: 1px solid #bbb; border-radius: 5px; z-index: 5;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span span.pssc_rootpoint[pointtype=""] {display: none;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span .pssc_rootpoint[pointtype="open"] {border: 2px solid red; background-color: white;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span .pssc_rootpoint[pointtype="closed"] {border: 1px solid red; background-color: red;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span .pssc_intervalline {display: block; height: 4px; position: absolute; left: -1px; right: -1px; bottom: -3px;}',
'.pssc_default table.pssc_table tbody.pssc_intervals td.pssc_interval span .pssc_intervalline[intervaltype="inside"] {border-bottom: 4px solid red;}',
'.pssignchart .pssc_toolbarwrapper {text-align: left; margin: 0; position: relative;}',
'.pssignchart ul.pssc_toolbar {list-style: none; margin: 0; padding: 0; position: absolute; top: 20px; left: -60px;}',
'.pssignchart ul.pssc_toolbar li {margin: 0.3em 0; padding: 0; display: block;}',
'.pssignchart ul.pssc_toolbar li a {display: block; border: 1px solid #777; border-radius: 4px; height: 20px; width: 20px;}',
'.pssignchart ul.pssc_toolbar li a.isopen {border-color: red;}',
'.pssignchart a.addrow span {display: block; height: 20px; width: 20px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFgSURBVDiNzVQxSMNAFH3/0rRm6yjiUlwCHcRN54Kbgzi4BFSos3RxtNTRpTgrqJBVHNwEZ93EoZBFXEQcC0Vi7pr7DpWmSe1VSwUf3HL337v//juOmBnThJiq2l8I5sYVHF0sVphjDwCILH9/6/HWVE+mGTbOl4qWVK8AO1/lYZy35+rbD+1RHLPlTuQqGTtKavRW7KATuSaK0bJSgEbagQAZexiyXGuUisLJuQAgYpSZ6DRDqGoLLQDQYTdo1p/bmfNEcO9woQLQNQDH2EaCEOC144OnflApy1LCo34AP4LDgAfge0El9ZgJDSP7RlKC3Uj7INrEbywz+4MbQ6Hs1EpFFSkXAJioDE6HAuIqMbcAwC7YwVnTEEoWG7vzy4JxN7inCSuXJy/3ozjmdxgCQqQv1No8ZaOg9W4HsvARIplpmI9mAhPHaBkAVtdnKxDs9doj/+bqbfLPYRL8/w/2E7FJjqbuDTz5AAAAAElFTkSuQmCC) center center no-repeat;}',
'.pssignchart a.removerow span {display: block; height: 20px; width: 20px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACOSURBVDiN7ZMhDsJQEETfNBhsD1GB4wzVSILp8eoq0ZwBV9FD4ADHYBC/TUt+0y8qOnKy+7Kb2ZVtUipLStuA6wTuhkYr5YIiptnQHexH6Cm8w7tUAldgHznQGzgd7dvohC+oZsD41VbAJHCxesAn1IILM1Y21KGh4S83Uv6JDCWD7vwvlBRa/2FvwOX6AlldJihgfCAkAAAAAElFTkSuQmCC) center center no-repeat;}',
'.pssignchart .pssc_toolbarwrapper .pssc_addrowbox {position: relative; border: none; border-radius: 0.5em; box-shadow: 0 0 3px black; padding: 0.5em; z-index: 10; background-color: #fefefe; margin-bottom: 0; white-space: nowrap;}',
'.pssignchart .pssc_newfunc_title {font-style: italic; margin-left: 1em;}',
'.pssignchart .pssc_newroots_title {display: inline-block; width: 1.5em; height: 1.5em; border: 1px solid #777; border-radius: 4px; text-align: center; text-decoration: none; font-weight: bold; color: black;}',
'.pssignchart .pssc_toolbarwrapper .pssc_newfunc {display: inline-block; min-width: 5em; min-height: 1.3em; margin: 0 1em; vertical-align: bottom;}',
'.pssignchart .pssc_toolbarwrapper .pssc_newroots, .pssignchart .pssc_toolbarwrapper .pssc_newroot1, .pssignchart .pssc_toolbarwrapper .pssc_newroot2 {display: inline-block; visibility: visible; min-width: 4em; min-height: 1.3em; margin: 0 0.5em;}',
'.pssignchart .pssc_toolbarwrapper .pssc_newroots[roots="0"] .pssc_newroot1, .pssignchart .pssc_toolbarwrapper .pssc_newroots[roots="0"] .pssc_newroot2, .pssignchart .pssc_toolbarwrapper .pssc_newroots[roots="1"] .pssc_newroot2 {visibility: hidden;}',
'.pssignchart .pssc_addfuncbutton {border: 1px solid #777; border-radius: 4px; text-decoration: none; font-weight: bold; display: inline-block; text-align: center; width: 1.5em; height: 1.5em; min-width: 20px; min-height: 20px; padding: 0; margin: 0.2em; vertical-align: top;}',
'.pssignchart span.mathquill-editable.inputerror {background-color: #faa;}',
'.pssignchart span.mathquill-editable {background-color: white;}',
'.pssignchart .pssc_totalwrapper {position: relative;}',
'.pssc_totalwrapper .pssc_totalundefined {position: absolute; left: 47px; top: -2em; width: 9px; height: 3em; background-color: transparent;}',
'.pssc_totalwrapper a.pssc_totalundefined:hover {background-color: rgba(255,255,0,0.8);}',
'.pssc_totalwrapper .pssc_totalundefined.isundefined {background: rgba(255,255,0,0) url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAYAAAARx7TFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEJwAABCcB2U8dgAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABESURBVAiZjc6xDYBADAPAC12moqb9ghlZg2kYIzSP9AVFLFkubNmOqrIiIhIHTuy4zVBi4MIzdSC/kl9j5aaDzlx0jr/6Nimp6cXzJwAAAABJRU5ErkJggg==) center top repeat-y;}',
'a.pssc_removerow_button {display: block; width: 15px; height: 15px; margin-left: -40px; border: 1px solid #777; border-radius: 4px; position: absolute; opacity: 0.7; border: none; }',
'a.pssc_removerow_button:hover {opacity: 1; border: 1px solid #777; margin-left: -41px; margin-top: -1px;}',
'a.pssc_removerow_button span.pssc_icon {display: block; width: 15px; height: 15px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAG7AAABuwBHnU4NQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFISURBVCiRhZO9ahtBFIW/c/cnCG8Q2IIQEUiTIo1rPYDwc7j3K9ilH8RNHiFlSJE3CCE4kCIhkBQmqwXbzWLNcSFZaFdiPTAw93IO37nDjGyzb/3JsrMSyhyqo+Xycp8m3y6+SecvIl5mQCnNJX2SPb8tiqqMIAPytr3AftgxAz9JaRSAs+w62RiukbCNVppN1I5ZcGrp0KvzZmODBBEt9tWTPnrkd0hfBRPsGfYHYCY4xv4IvN8W9821Uvpt+AUQWfYFwNKNI37YXgyZF444AO46XbuRPRY0g2SgknTf6ze2x8AwWXDgPhkaRTxrrg2VoEuWVmRpMPYCe4csuxGMBy9MsDBUSqlDTuuZQ+qY+y+s3juztCKn9ExseK2INwBeLmfr2K+At/TI2v5V36Uqh5MCpnnEtJQmuVQX0t9C+jdq28/Y/5/0jzvgjtI+Y4wZAAAAAElFTkSuQmCC) center center no-repeat;}',
'.pssignchart .pssc_addrowbox a.pssc_addfuncbutton span.pssc_icon {display: block; width: 1.5em; height: 1.5em; min-width: 20px; min-height: 20px; background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJOgAACToB8GSSSgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFgSURBVDiNzVQxSMNAFH3/0rRm6yjiUlwCHcRN54Kbgzi4BFSos3RxtNTRpTgrqJBVHNwEZ93EoZBFXEQcC0Vi7pr7DpWmSe1VSwUf3HL337v//juOmBnThJiq2l8I5sYVHF0sVphjDwCILH9/6/HWVE+mGTbOl4qWVK8AO1/lYZy35+rbD+1RHLPlTuQqGTtKavRW7KATuSaK0bJSgEbagQAZexiyXGuUisLJuQAgYpSZ6DRDqGoLLQDQYTdo1p/bmfNEcO9woQLQNQDH2EaCEOC144OnflApy1LCo34AP4LDgAfge0El9ZgJDSP7RlKC3Uj7INrEbywz+4MbQ6Hs1EpFFSkXAJioDE6HAuIqMbcAwC7YwVnTEEoWG7vzy4JxN7inCSuXJy/3ozjmdxgCQqQv1No8ZaOg9W4HsvARIplpmI9mAhPHaBkAVtdnKxDs9doj/+bqbfLPYRL8/w/2E7FJjqbuDTz5AAAAAElFTkSuQmCC) center center no-repeat;}',
'.pssc_inequality {margin-bottom: -1em;}',
'a.pssc_ineqlink {color: black; text-decoration: none; display: inline-block;}',
'a.pssc_ineqlink .pssc_ineq {cursor: pointer;}',
'.pssignchart.editmode .pssc_ineqrelation {color: red; font-weight: bold;}',
'.pssignchart .pssc_removerow_button {display: none;}',
'.pssignchart.editmode .pssc_removerow_button {display: inline-block;}',
'.pssignchart a .pssc_text {display: none;}',
'.pssignchart a .pssc_icon {display: inline-block;}'
].join('\n')
}
/******************************************
* Row of signchart
******************************************/
var PsscRow = function(options){
options = $.extend({
func: '',
roots: [],
motivation: 0,
signs: []
}, options)
this.func = options.func;
this.roots = options.roots;
this.motivation = options.motivation;
this.signs = options.signs;
for (var i = 0; i < this.roots.length + 1; i++){
this.signs[i] = this.signs[i] || '';
}
this.roots.sort(function(a,b){return (a.value < b.value ? -1 : 1)});
}
PsscRow.prototype.getRoot = function(num){
return this.roots[num];
}
PsscRow.prototype.getRootVal = function(num){
return this.roots[num].val();
}
PsscRow.prototype.getRootLabel = function(num){
return this.roots[num].getLabel();
}
PsscRow.prototype.getRoots = function(){
return this.roots;
}
PsscRow.prototype.getFunc = function(){
return this.func;
}
PsscRow.prototype.getSign = function(n){
return this.signs[n];
}
PsscRow.prototype.setSign = function(n, sign){
return this.signs[n] = sign;
}
PsscRow.prototype.getMotivation = function(){
return this.motivation;
}
PsscRow.prototype.setMotivation = function(mot){
return this.motivation = mot;
}
PsscRow.prototype.getData = function(){
return jQuery.extend({},{func: this.func, roots: this.roots, motivation: this.motivation, signs: this.signs});
}
PsscRow.prototype.isRoot = function(root){
var isroot = false;
for (var i = 0; i < this.roots.length; i++){
isroot = this.roots[i].val() == root.val();
if (isroot){
break;
}
}
return isroot;
}
PsscRow.prototype.nextMot = function(){
this.motivation = ((this.motivation + 1) % Pssignchart.mot.length)
return this.motivation;
}
/*******************************************
* Root on a row of signchart
*******************************************/
var PsscRoot = function(options){
this.label = options.label;
this.value = options.value;
}
PsscRoot.prototype.isEqual = function(other){
return (this.value === other.value);
}
PsscRoot.prototype.val = function(){
return this.value;
}
PsscRoot.prototype.getLabel = function(){
return this.label;
}
var latexeval = function(expression){
var latexrep = [
[/\\sqrt{([^{}]*)}/ig, 'sqrt($1)'],
[/\\frac{([^{}]*)}{([^{}]*)}/ig, '(($1)/($2))'],
[/((?:[0-9]+)|(?:\([^\(\)]\)))\^((?:[0-9])|(?:{[0-9]+}))/ig, 'pow($1, $2)']
]
var reponce = [
[/\\left\(/ig, '('],
[/\\right\)/ig, ')'],
[/\)\(/ig, ')*('],
[/\\cdot/ig, '*']
]
var oldexpr = '';
while (oldexpr !== expression){
oldexpr = expression;
for (var i = 0; i < latexrep.length; i++){
expression = expression.replace(latexrep[i][0], latexrep[i][1]);
}
}
for (var i = 0; i < reponce.length; i++){
expression = expression.replace(reponce[i][0], reponce[i][1]);
}
var reg = /(?:[a-z$_][a-z0-9$_]*)|(?:[;={}\[\]"'!&<>^\\?:])/ig,
valid = true;
expression = expression.replace(reg, function(word){
if (Math.hasOwnProperty(word)){
return 'Math.'+word;
} else {
valid = false;
return word;
}
});
if (!valid){
alert('Invalid expression!');
} else {
try {
return (new Function('return ('+expression+')'))();
} catch (err) {
throw 'Invalidexpression';
}
}
}
})(jQuery)
//}}}
//{{{
config.macros.pssignchart = {
/******************************
* Show signchart
******************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
if (params.length < 1){
wikify('Missing signchart.', place, null, tiddler);
return false;
}
var psscid = params[0];
var iseditable = (params[1] === 'edit');
var isauthor = params[1] === 'authordialog';
var pssctext = '{{pssc pssc_'+psscid+'{\n}}}';
// wikify(pssctext, place, null, tiddler);
wikify(pssctext, place);
if (tiddler) {
var settings = jQuery.extend(true, {},DataTiddler.getData(tiddler, 'signchart',{}));
} else {
var settings = {};
}
if (typeof(settings[psscid]) === 'undefined'){
settings[psscid] = {rows:[], total:{}, intervals:[], rootpoints:[], undefinedpoint: []};
}
settings[psscid] = settings[psscid] || {rows:[], total:{}, intervals:[], rootpoints:[], undefinedpoint: []};
var startoptions = {};
startoptions.mode = (iseditable || isauthor ? 'edit' : 'view');
var thisChart = jQuery(place).find('.pssc.pssc_'+psscid).last()
.pssignchart(startoptions)
.pssignchart('set',settings[psscid]);
if ((iseditable || isauthor) && params[1] !== 'authordialog') {
thisChart.bind('pssc_changed', function(e){
var $psscplace = jQuery(this);
var data = $psscplace.pssignchart('get');
var settings = DataTiddler.getData(tiddler, 'signchart',{});
settings[psscid] = data;
var autosavestatus = config.options.chkAutoSave;
config.options.chkAutoSave = false;
tiddler.setData('signchart', settings);
config.options.chkAutoSave = autosavestatus;
});
}
}
}
//}}}
!usage
{{{[img[racing_flame.png]]}}}
[img[racing_flame.png]]
!notes
Image for "flame" theme.
!type
image/png
!file
./data/images/racing_flame.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[rose.png]]}}}
[img[rose.png]]
!notes
Rose for ThemeStyle_Rosy
!type
image/png
!file
./data/images/rose.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[skull_hat.png]]}}}
[img[skull_hat.png]]
!notes
Image for "skulls" theme.
!type
image/png
!file
./data/images/skull_hat.png
!url
!data
data:image/png;base64,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
//{{{
EbSolutionElement.prototype.getWikisderivation = function(inputdata,iseditable){
return '<<qedderiv [['+inputdata+']] savehere>>\n';
}
EbSolution.prototype.addDerivation = function(){
var derivations = DataTiddler.getData(this.tiddlerName, 'derivations', {});
var index = 0;
while (typeof(derivations['sderiv'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"sderivation","data": 'sderiv'+index};
derivations['sderiv'+index] = {"task":[],"assumption":[],"observation":[],"derivmotivation":[],"term":[{"text":""}],"relation":[],"motivation":[]};
DataTiddler.setData(this.tiddlerName, 'derivations', derivations);
var element = new EbSolutionElement(elementdata);
this.addElement(element);
this.save();
}
//}}}
<data>{"addElement":{"elementType":"derivation","addFuction":"addDerivation"}}</data>
//{{{
EbSolutionElement.prototype.getWikiemfuncgraph= function(inputdata,iseditable){
return '<<emathfuncgraph [['+inputdata+']]'+iseditable+'>>\n';
}
EbSolution.prototype.addEmathfuncgraph = function(){
var emfuncgraphs = DataTiddler.getData(this.tiddlerName, 'emathfuncgraph', {});
var index = 0;
while (typeof(emfuncgraphs['emfg'+index]) !== 'undefined'){
index++;
}
var elementdata = {"type":"emfuncgraph","data": 'emfg'+index};
emfuncgraphs['emfg'+index] = {editable: true};
DataTiddler.setData(this.tiddlerName, 'emathfuncgraph', emfuncgraphs);
var element = new EbSolutionElement(elementdata, true);
this.addElement(element);
this.save();
}
//}}}
<data>{"addElement":{"elementType":"funcgraph","addFuction":"addEmathfuncgraph"}}</data>
//{{{
EbSolutionElement.prototype.getWikisignchart = function(inputdata,iseditable){
return '<<pssignchart [['+inputdata+']]'+iseditable+'>>\n';
}
EbSolution.prototype.addPssignchart = function(){
var pssigncharts = DataTiddler.getData(this.tiddlerName, 'signchart', {});
var index = 0;
while (typeof(pssigncharts['pssc'+index]) !== 'undefined'){
index++;
}
var elementdata = {"type":"signchart","data": 'pssc'+index};
pssigncharts['pssc'+index] = {rows:[], total:{}, intervals:[], rootpoints:[], undefinedpoint: [], editable: true};
DataTiddler.setData(this.tiddlerName, 'signchart', pssigncharts);
var element = new EbSolutionElement(elementdata, true);
this.addElement(element);
this.save();
}
//}}}
<data>{"addElement":{"elementType":"signchart","addFuction":"addPssignchart"}}</data>
//{{{
EbSolutionElement.prototype.getWikiemtable= function(inputdata,iseditable){
return '<<emathtable [['+inputdata+']]'+iseditable+'>>\n';
}
EbSolution.prototype.addEmathtable = function(){
var emtables = DataTiddler.getData(this.tiddlerName, 'emathtable', {});
var index = 0;
while (typeof(emtables['emtable'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"emtable","data": 'emtable'+index};
emtables['emtable'+index] = {editable: true};
DataTiddler.setData(this.tiddlerName, 'emathtable', emtables);
var element = new EbSolutionElement(elementdata, true);
this.addElement(element);
this.save();
}
//}}}
<data>{"addElement":{"elementType":"table","addFuction":"addEmathtable"}}</data>
//{{{
EbSolutionElement.prototype.getWikitext = function(inputdata,iseditable){
return '<<solutiontext [['+inputdata + ']]'+iseditable+'>>\n'
}
EbSolution.prototype.addText = function(){
var mathtext = DataTiddler.getData(this.tiddlerName, 'mathtext', {});
var index = 0;
while (typeof(mathtext['mathtext'+index]) != 'undefined'){
index++;
}
var elementdata = {"type":"text","data": 'mathtext'+index};
mathtext['mathtext'+index] = '';
DataTiddler.setData(this.tiddlerName, 'mathtext', mathtext);
var element = new EbSolutionElement(elementdata, true);
this.addElement(element);
this.save();
}
config.macros.solutiontext = {
/**********************************************
* Insert Mathquill-textbox. The content will
* be saved in this tiddler with DataTiddler-plugin
* on each focusout.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var textid = params[0];
var iseditable = (params[1] == 'edit');
var solclassstart = '{{sdbooksoltext mathtext_'+textid+'{';
var solclassend = '}}}\n';
var textdata = DataTiddler.getData(tiddler, 'mathtext', {});
var text = textdata[textid] || '';
if (iseditable){
var result = solclassstart + '<html><span class="mathquill-textbox" latex="'+text+'"></span></html>' + solclassend;
} else {
var result = solclassstart + '{{solutiontext{'+text+'}}}' + solclassend;
}
wikify(result, place, null, tiddler);
var mathelement = jQuery(place).find('.mathquill-textbox:not(.mathquill-rendered-math):last');
var latex = mathelement.attr('latex');
mathelement.empty().append(latex);
var edata = {'tiddler': tiddler.title, 'textid': textid};
if (iseditable){
mathelement.mathquill('textbox');
} else {
mathelement.mathquill('embedded-latex');
}
mathelement.focusout(edata, function(e){
var latex = jQuery(this).mathquill('latex');
var textid = e.data.textid;
var tiddler = e.data.tiddler;
var mathdata = DataTiddler.getData(tiddler, 'mathtext', {});
mathdata[textid] = latex;
DataTiddler.setData(tiddler, 'mathtext', mathdata);
});
}
}
//}}}
<data>{"addElement":{"elementType":"text","addFuction":"addText"}}</data>
!usage
{{{[img[sports-1.png]]}}}
[img[sports-1.png]]
!notes
Theme image: sports 1
!type
image/png
!file
!url
!data
data:image/png;base64,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
!usage
{{{[img[sports-3.png]]}}}
[img[sports-3.png]]
!notes
Theme image: sports 3
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAABGCAYAAACQRffVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKBAAACgQBvH9LLgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAuxSURBVHic1Zt9eNTVlcc/Z5JM3t8mL5OZvEMi4R1FkSJqXSgILSrFB8si20WFhYLaVqxLWaVVl7bYiri4q6jbVqQsivtg1FKQRbS1QIlaDBQsEUgC5HXynpm8ztk/kmgSJslM5ick3+e5f8zvnnvO/c49v3PvPff+RFUZShARc4qVXdHhjG9phZY2TpU6eK6pWd82xICqDqliT+D9Xb/ApXmo5qGFb6M/XEx1uo1jQIa/+q84we4lIIAbl83H0UW2e/n8TTTTznkgxh8bJkPcxCCkJ7F+7VIsnupGJMMj3yUhNJjb/bExpAgjJGXa+66eMg5zTCQr/TExpAirG7fb3Xf9iGQIMeNXlB1ShIFjn3zWd2VLK/g7qQwpwoWlvP5eHo191Z8rgdZ2XP7YGFKE3W6cpQ6a+6p/9zCNjhpe8MdGoD+NjYKIxKZa2TVtAqPvnkNsX3K/fZvqphbe8MfWFSMsImHACCDTnsCGHRsYc8NEzx53oRz+axe1jU0UqmqbX3avxNIy1SrbUpO4ZXQGATkZhM+8nsirR3mWdTXDrFU0fnSSd13NLFDVfuL4wLjshG3x8tCy+Tz6+AqivW3jdsPDm6l77V1eKy7TZf7Y/8oJi4iEhXCrLZ77gRHpNiz7niMhYBDh8t7Hqf3vXBao6v8Ntj9f2TssIuGJsXwvM5mVC2cSt/JOotJt/ulctZDo/X9hCTC0CItIUkoiB9cvJ3PJXMzBZmP0TroKRLhGRBKBKFUt8FWH4YRFxJJi5dDbm0ifeBVipO6yKqhtwJxh52h7O40iMl5V233RYfjCIyGG5RtWkdybbL0T8gvggaeoSp1L1alzvuvO/YDmtnZei4/G/Mh3Sbcn8ISvOgwf4bBQ7rlzBkEAW3ZS/+Juql1NuNraqVY4faGcV1IS+YXV4nkb2B8aXbQ3ODlU6iDOnsDyNCv3isg2VT3prQ5DCYtI2A0TiQgNhpJKeGobZ4pKuVp7TQU5GRIRG+W7/nQbYeYgUs+Xs3btFm5/axPJ/7CC10VkoreubbRLjxwzouNP3H2Q5qo6nu5NFiAwAL/CmKrW1Tbw7N7DuH6wmIxEC49529ZowtkTs4kE2LEXR4OT3N4CIhIVF93h8r6iqpbmABNNAKUOnn76Vcruu4PwmVP4XrpN8kRkwMWMoYTjYhidYSfE1QwXynGoao0HsaxxIwc3wskJmGKjWC0iIUBcSSV7f/4bnNufJH7rOiamJbFhIB2GvsMRoaTGRcOBo6izif/1JBMQwNhrxxDjjb6aeoiJ/PL33OkEvbiOSas3ci47DWZeT/TMKYQAzP4agRFh3CEi9/e33jZ0hIMCsCbEwvY9lJc62OFJxhbHlNGZ3rn0uv+k5bPCns/mTifoTC7WvVuwfvMGQvYfwbXkUcqPnkDjojEB/YZDY6clwWKJgmOnaVdVj8mawADGZ6cNrKqsCt75E5UHjiIHt2KzWjrm8oJi+Owc+tzrVBSXkV9Ywi+B8/v/wpuBgXwKNPSn11DCqgQFBQLad6LNZMIe58U+ac0zVJ4v566oMEKmLWUdkOBWqlH+VlnLxw1Ofq+qxV3ynVNTv2TB+IVHgMkEimfCIhI2bQJh3ij68Bi1bW36p86f+weS94YsGPwOqxIWYoaURIJEZEzv+gATN82YQsRAes6Xg8BZI/vWBUMJhwYTYTLB8z/GmmplW/c6EQmwJ/DMqoUDb/z3H6G1ph5jDs96wTDCImIKDSEYOhLmc6aRKSKzuurjY1j24CJSrF6soF/aTUVVXc8/zCgYOcKh0qmvpBIO5OECDgGISGBEGI+sXkj4QEpUodRBm6pWGdi3L2Bk0HJdrGRP9nzmtrZxprqOx1S1vrPu1qXziPcmEXA4H1rbOGhgv3rAMMKdq5ulIhKqqj1OB0yCZUQyod7oaWkDt1JtVL96w/AEQG+yAG7l0yPH8cpFw0PA7SbH6H514XIdtRw/lN+xyxkI146Be25jWlqSvCoihqaI4DIRVtW2qlpqm1u8k39iJZEPLeGOlETeEZFBbSX7wmU7TKupZ9MzO6gfWLIDD36H8PXLucUWz04j+3HZCLtaKC4optWXNvfdQcg/fZMZtngZcJ/rLbw+eejMBYep6rnBGMqwS/7H2xlnGUQua/4aHH/8hAcra3T7YGx3R78jLCLRlmhZlZksn9w8mb9OGsVhEZnqqxERGXndGBIGQxZg58+Ii43iSRHxO6XfYx4WEVNMJHdaovlXcyAxX5uAeek84u+aRXBUOJw8C7NWsR6Y44uRYDPXz7nB97RsF8xB8PgKbD/aTK6IzPGUGPQWXxAWEVuqlbeW3saoHy4mItrDnmZ0Jiy6lalpSXKouIwVqnrMGyPJCXx90lV9Zzna3TDQ4dqi2QQXlzH92R38FLzPUvaGCSA8VKZlp/FR7iYm//RfPJPtwsYHiDnwPFO/M4t96TY5YYmS+0WkX2c1mbgqLanv+hfewHnNYip7p3N64+ElhI9IYUVUhMzuX7JvCDBqzAgOfPgy9u4JM2/Q4ITf/YHmLa9RWdvAnqJS1qvqxd5yWanyt4LdjPako90NOQsoLijmWylWfr1oNiPXLyM6vI+FaF0jTL+XsvwCZqrqcd96DJJu49MPX2Z8SSV635OUt7biBggKBHsiZNgIzLATEh2BOTiIgGAzAeNGIuOzeip6/yPcj71AaVEJ9SL8va6RPzpqeUtVT+VkSMGpNxjpqQPb99D68GZ+drFC1wNYomRxdCRPPnQ31ntvJzQ0+NI2Fytg6lI+LyrRrEtrByAcGU71wpm07ztMYXEZs1TVAR0bdiARSOosYYDZJASn25htMjH1xquJ2rwGS1S3TZ8qfH4ejp2G7Xuo+OQzagXizuReellFFcYupOTkWUZ121khIkHxMayIiWDlvJtIeur7xPZ+x69ZTPHHp9SLdOClSASuA4J8vagZFc43slIpPvRr2j1dCO0qF/Zc+sx9FF02n6pUKz/p93ZtPMtnTKHC9eee7Sdkc3ZQl0tVtVxVj6qqT6sggNoGfbegmEl3reXgig04qus8y9kTLn32yH9Qm/s+zxeV6k/6s3GhQrceL+C5vYd6JgYbnIO7oOb30lJVHYUlOuOVd1g4+W5ObnyF+pYB/rrf/YGmV3/Pe6UO/bE3Nsqq2PteHo7uz4ICvdtf94Zha2lnkx44e5GxG3/LmnELKXz5TZpaPdyo+nsR/Ggzp0squcsH9WUV1T3X4eOyCBaRdF/7aXCaVrWyRreeLmb02i2sz1lA0abtOLtGXBWWPErJhQrmq6qXm0UAmp1NPV163o3ER4YzYzCd/MoKEJgYy+qsVAp/9QNcV4/iYnIiywejZ1wWRb0DYaadfT7r+ioJd+twcHgoy4HkwepIt/Hnsn09I3VOBucAk09R2meXGARUtbnBqVtV9cJgdZRX8W//uI4K7ebYt91MNHCzL3qG1PXh/uBs0gMnzvDsEy9R2/Vs6TxiMuw84IueYUMYoNTBv7+0m+qmznCXkwGhwUwWEa/TzcOKsKqqq5kX/2fvl1PUt6YThS9ufTmClsEBMHZCNhe7AtdHr6LpNnYOqaBlJFS1uraBv3btna/JARGmeZvDHnaEAQpLeOr5XV8ex3x9MqHAtd60HZaEgYO5H1Df9Y3T4jnEJSdyjzcNhyVhVdWWVnLfy+tYbt5yLVgtfFtExnrTeFgWIPu2mynt/hXqdWMpTUviKBDfKZMFLABu+qLdle64PyXDzon6D+ix3MzbRvuodIpt8ZQDmhTHESATiANChqVLfwHlaO9715NHYzr1BinfX0REciLlYSE0pyWxc8Z1nLDFk3dFPuMxCgmxsmbrOjbOv6Xvm/flVR2fAiXFwagFFA/rEa6s4cC+w/3fFki0QFgITL+PkgYnq4fEp3h+IP9QPk2qIAKlDqisgeCgjt+OWjhyHOem7ZScK2G+quYPa5cGSLHKE+ZA/tkchMvtpgjhgkCoKqaWNkqr6vi4vpFt2pmk/H+Cgea9Wyh5rQAAAABJRU5ErkJggg==
!usage
{{{[img[tausta-red.jpg]]}}}
[img[tausta-red.jpg]]
!notes
//none//
!type
image/jpeg
!file
!url
!data
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0//wAARCAHkB9ADASIAAhEBAxEB/8QAGwABAQEAAwEBAAAAAAAAAAAAAAECAwQFBgf/xABDEAEAAgIBAQQGBwgBAgUDBQAAARECAwQhBRIxUQYTIkFhcRQjMkKBkaEzNFJicrHB0XMk4RU1Q4LwJWOSRKKywvH/xAAaAQEBAQEBAQEAAAAAAAAAAAAAAQIDBAUG/8QAJREBAQACAgICAgMBAQEAAAAAAAECEQMxEiEEQTJREyJhQjNS/9oADAMBAAIRAxEAPwDwRR5H6FBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQEFAQUBBQGqKUESilASilASildrjcLZv4nJ5MdNfHxiZnzmZiKEt126lFKCpRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgJTt9la9e3tTjat2MZa9mcYZR8+jqux2dl3O0uLn/Duwn9YWJl1XJ2v2bs7M5uWjO5wnrrz/ih0qfo3bPZmHafCnVNRtx668vKf9S/PNurPTty1bcZxzwmson3SuWOnLh5fOe+2KKUZdkopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopSYmJqYqQSilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilAUWigQWigcvH4fI5Xe+j6stk4Rc449Zr5eMuLPXnrynHZhljlHjGUVLl4vI28TkYb9GU47MJuJfd9n8vh9t8KMtunXnnj02a84ie7P+mpNuPJyXD3r0+A1689u3HXrxnLPOYjGI98vteV2fh2f6Kb+NjU5Rh3s8vPK4uXc4/YnZ/G5mPK0ae5njdR3pmI+NS5+09GfK7O5GjXXf2YTGNz725jp5+Tnmdmun5qPR39idp8e+/xNkx54e1/Z0MsMsMpxzxnGY90xTnp7JlL1WRaKRpBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBGteXc24Z/wzEpRQj9TfOelXZH0jVPO4+P1uuPrIj72Pn84/s9/j5d/jas/wCLCJ/RyO9m4+XhlcMtx+Vj3PSTsj6DyfX6Mf8Ap9s9Ij7mXl/p4lONmn08cplNxBaIiZmoi5RpB6/B9Hu0OXWU6/Ua5+9s6fp4vouD6McHjVlvvkZx/H0x/L/bUxtcc+fDF8bxuFyeVc6NOWWOMXll4Y4/OfCHBMdX1PpR2njhj/4ZxKxxj9r3ekf0vl6SzTXHlcpuoLRSOiC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UCC0UDl4XHnlc3Tx4/8AUzjH5R73pelHEjjdsZThjWG3GM4iPyn+zn9EON63tTLdMdNOEz+M9I/S3pemXG7/AAtPJiOurPuz8p/7x+rcn9dvPlya5Zi+OFpYxmfCJlh6GRaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBIiZmoi5lc8MsM5wyiYyxmpjyl9N6K9keszjtDkY+xjP1WM++fP8Hzm/Lv79mf8AFlM/qtmoxM5crJ9OMWikbQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigSnucnsr/wAP9HfX78a5G/ZjFT9zHrNfPo5/Rbsj6RtjncjH6rXP1cT97Lz+UO/6Z5f/AE/Rh57b/KJ/23MfW3nz5d8kwj40WimHoQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigQWigWilBEopQEp6vo5hysu19f0TLu112T7u777eZjjOWUY4xMzM1ER732/Zmji9hdnRPL24a9uz2s5mes/CPOmsZ7cubPxx1917JMxETMzUR4zL5zd6WaY5GOOnRllqv2s8pqa+EPfjLXyeN3teUZa9mPSY98S6yyvBlx5Y/lHmcz0j7P4144bJ35x7tfWPz8Hz3aPpFyObjOvHTp16/jjGc/nP+njzFTMT4wjncrXuw4MMUKUYdkopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQH6P2Xl3+yuJl56cP7Q7Tz+wcu92JxZ/kr8pp6D0Tp8rP1lXFyuNq5fGz0bse9hnFT/t8Fyex+Zp5+fE16c9uUdcZxjpMe6fg/QhnLHbfHy3j6fI8H0T251lzt0a4/gw6z+fhH6vouF2XwuDEfR9GMZfxz1y/N3BZjImfLnn3R5nbvakdm8OZwmJ37OmuPL4/g73J5Gvi8fPfuy7uGEXMvz3tHm7O0OZnyNvS+mOP8Me6Eyum+Di87u9OrlOWeU5ZTM5TNzM++UpRxfQSilASilASilASilASilASilASilASinNx9frNsRPhHWXHMVMx5AzRSgJRSgJRSgJRSgJRSgJRSgJRSgJRSgO/wBl9r8rs3Ktc9/TM+1qy8Pw8pfZdndo8HtPXeqMY2RHta8ojvR/t+fObiRtnlasePlljtyyiMJxmpiZbxysceThxy99V+k4a8ML7mGON+NRVrljjlFZYxlHlMWYROOGMTlOUxFTM+9XV851uVv4nB0zt3zhrxjw6dZ+EQ+R7X9IeRze9p496eP4VE+1l85/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rjfbbjz65ORxz4kbzrI0K5sjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyqgN4zcM7PtGM1Jn4o3buMDQrDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAMjQDI0AyNAGvPLVsx2a8qyxm4n4plPeymZ8Zm1AZGgGRoBkaAZGgGRoBkaAZGgGRoBaKUESilASilASilASilASilASljoALEqysdE03M/2oWI6AAAAAAAJMiW6JllRrTlctpRSgiUUoCUUoCUUoCUUoCUUoCUUoCUUoCU5tfHzz4+3fEVhrq585mapeLx9nK5GOnVHtZe/yjze72to18PsSNGqOneiL858bWRjLPVkfN0UojaUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCUUoCLcgLsuV73wQTS+VWy4QNHnWrgZaSxvHLYANAlrZpPKBMWWC9szFJTbNLK5ZY6SilFZSilASilASilASilASilASilASilASilASilASilASilASilASilAShQFnwZppEjWV3UopRWUopQEopQEopQEopQEopQEopSgSilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilASilAShQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQEopQFopQEopQEopQEopSgSilASilASilASilASlAJdADLtOgAUAAlKUajll2lFKDKUUoCUUoCUUoCUUoCU13Mu53+7PdurrpaO72ZzI4u/u7IjLRs6Z4zF/iqW2T06NFPqOT2LxORHf0/VTPWJx64z+Dx+V2Ry+Pcxh6zDzw6/otxsYx5ccnn0U1VeKMuiUsRMzERFzPhA9zsLs+5jl7sekfs4n+6ybYzymM3Xe7I7PjhcfvZx9dn9r4fBwekk/9Fqx89l/pL13ieks+xx8fOcp/s3fUeXC3Lklr5+ilHN7UopQEopQEopQEopQEopQE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igQWigQWigQWigQWigel2LPtbcfOIn+709mvHbrywzi8coqXk9jzXKyjzw/zD2G5083J6yfO8rj5cbdOGXWPHGfOHC+h5fGx5OmcJ6ZR1xnyl4GeGWvOcM4rKJqYZs07YZ+UZFp2NHC376nHCsf4sukI3bJ26zk06Nu+a1YTl8fc9bR2Zp11OyZ2ZfHpDtbM8NGmcpiMccY8IXxcry/UeJyeJHF1x6zO9mXhjj7odZy79uW/dlsz8Z93k46R0m9e0FooVBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBBaKBGMM4zyyiPDH3scnb3I7mP2p/ROJHsZT8U37b8f67rnFopWEFooEFooEFooEFooEFooEFooEFooEFooEFooEFooEFooEFooEFooEY2YRswnGfwclAsunm5ROOUxPjCOXfnjnsvGOkdL83E5vVPcABRccssZ9mZhAHPjyco+1ES5sd+vL31PxdIXdYvHK9GOvgrz8c8sfszMObDk5+GWPe+S+TneKzp2hMMu9F93KPnDVNOaC0UIgtFAtFLRQJRS0UCUUtFAlMbNuOuPa8fKHJRQR0NnIzz6R7MfBwvUnDGfHGJ/BmdOufuY/kz4u05JPp5o9GePqn7n6szxNU+cfinjWv5cXQHdnh4e7LJmeH5bP0PGr/Ji6g3twnXnOMzdMI3LsAAAAb17MteV4/jHmwBZt6OrZjsxvHx98eTdPNwyywy72M1Lvad2O2PLL3w3Lt588Ne45KKWilc0opaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEoouJmYuLj3LQJRS0UCUUtFAlMbdka8O9Pj7obmYxiZmaiHn7tk7c793uhLdN4Y+VcvEmctuWU9Zp26dbgx9ufk7VE6OT8kopaKVhKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooGtWzPVl3tc1l4XXgmeeeybzynKfOZtKKESilooVKKWigb0bctG7HZj7vGPOH0GvPHZrxzwm4yi4fOU9Hsvkd3L1Gc9MuuPzalcuTHc27faP7js/D+8PCp7vaP7js/D+8PDoyOLpKKWimXVKKWigSilooEopaKBKKWig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BKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooGZqIufB5fJ2Y7N05YRUeF+bm5vJ70zq1z7MeM+bpsZV6eLDXugDLqAAC445ZTWMTM/CHNhxN+X3O7Hxk0lsnbgbw27Nf2Mph28Oz/AOPZ+EQ58OHpx+73p+MrMa53lxdbVzc7rPDvf0+Lu4Zd/G+7lHwyimscMcYrHGIj4QtNxwysvUSilopWUopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopad7g8W63bI6fdj/ImWWpty8HjTqx9Zn9vKPDyh2wbea3d2ACAMbN2vV9vOInyBsdTPtDVH2Mcsv0cGfaG2fsY44/qm43MMq9J19+HFm/W9yJ+dS83Pftz+1syn4W46Tbc49fbk346In6nPLL5w4qWikdYlFLRQJRS0UCUUtFAlFLRQJRS0UCUUtFAlFLRQJRS0UCUUtFAlFLRQJRS0UCUUtFAlFLRQJRS0UCU9zT+w1/0x/Z4lPa4/wC76/6Y/suLly9OR5/aW/w04z8cnc37Y06pzn3eEecvGymcspyym5mblbWePHd2zS4zOM3jMxPnElFMu7n183fh45d6P5na19o4T+0wmPjHV51FG2bhjXp7vUczXWOzHvx9m+kvMzwywynHKKmPEom58ZstMcfFKKWihpKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilonpFyDOUxhjOWU1EPK5G6d2d+GMeEOTl8j1uXdx+xH6us55V6ePDXugN4as9n2MJn5QjqwLPSalAHLhxt2fhrn8ejGv9pj84e1Sybc+TO49PPw4Gc/bziPl1c2HC1Y/avL5y7VFN6jheTKuPHVhh9nCI+UN0tFKxtKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBKKWigSilooEopaKBjPCNmE45R0kwx7uGOPlFN0ULtKKWihEopaKBKKWigSilooEopaKBRQEFAQUBBQEFAQUBBQEZjCIzyzjxyq2wNoKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAgoCCgIKAg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
!usage
{{{[img[tausta.jpg]]}}}
[img[tausta.jpg]]
!notes
//none//
!type
image/jpeg
!file
!url
!data
data:image/jpeg;base64,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
/***
|''Name:''|teacherElement.js|
|''Author:''|Petri Sallasmaa, Petri Salmela|
|''Description:''|Teacher element show/edit functionality for E-Math ebook|
|''Version:''|1.0|
|''Date:''|May 31, 2012|
|''License:''|[[GNU Lesser General Public License|http://www.gnu.org/copyleft/lesser.html]]|
|''~CoreVersion:''|2.6.2|
|''Contact:''|pesasa@iki.fi|
|''Dependencies ''|[[DataTiddlerPlugin]]|
|''Documentation:''| |
!!!!!Revisions
<<<
20130926.1120 ''fix''
* emathfuncgraph: added div with ebelement -class around it.
<<<
!!!!!Code
***/
//{{{
/*******************************************************************
* teacherElement.js
* Teachers element show/edit functionality for TiddlyWiki-ebook
* Petri Salmela
* Petri Sallasmaa
* 31.05.2012
*******************************************************************/
/***********************************************
* EbTeacher -class
* One teacher element
***********************************************/
EbTeacher = function(options){
options = options || {};
this.tiddlerName = options.tiddlerName || '';
this.place = jQuery(options.place) || jQuery('<div></div>');
this.editable = !!options.editable;
this.assignment = options.assignment || '';
this.elemtype = options.elemtype || 'text';
this.title = options.title || '';
this.elements = [];
this.creator = '';
this.ispublic = false;
}
EbTeacher.prototype.initElements = function(){
var teacherelementdata = DataTiddler.getData(this.tiddlerName, "teacherelement", {"creator":"","teacherelements":[], "editable": true, "ispublic":false,"title":"","elemtype":""});
this.creator = teacherelementdata.creator || config.options.txtUserName;
this.editable = !!teacherelementdata.editable;
this.ispublic = !!teacherelementdata.ispublic;
this.elemtype = teacherelementdata.elemtype || (this.hasTool && this.hasTool.elemtype) || "text";
this.title = teacherelementdata.title;
var elements = teacherelementdata.teacherelements || [];
for (var i = 0; i < elements.length; i++){
var elem = new EbElement(elements[i], this.editable);
this.addElement(elem);
}
}
EbTeacher.prototype.editElements = function(){
var teacherelementdata = DataTiddler.getData(this.tiddlerName, "teacherelement", {"creator":"","teacherelements":[], "editable": true, "ispublic":false,"title":"","elemtype":"text"});
var elements = teacherelementdata.teacherelements || [];
this.elements = [];
for (var i = 0; i < elements.length; i++){
var elem = new EbElement(elements[i], this.editable);
this.addElement(elem);
}
}
EbTeacher.prototype.save = function(){
var teacherelementdata = {
"creator": this.creator,
"editable": this.editable,
"ispublic": this.ispublic,
"elemtype": this.elemtype,
"title": this.title,
"teacherelements": []
}
for (var i = 0; i < this.elements.length; i++){
teacherelementdata.teacherelements.push(this.elements[i].getData());
}
DataTiddler.setData(this.tiddlerName, 'teacherelement', teacherelementdata);
}
EbTeacher.prototype.addElement = function(element){
this.elements.push(element);
}
EbTeacher.prototype.removeElement = function(index){
this.elements.splice(index, 1);
this.save();
}
EbTeacher.prototype.getWiki = function(){
var wikitext = '{{teacherset{\n';
var ending = '}}}';
// "boxing" some elements
switch (this.elemtype){
case "theory":
case "text":
case "example":
wikitext += '{{ebookbox{\n{{sdbook'+this.elemtype+'{\n';
ending = '}}}}}}}}}';
break;
/*case "assignment":
wikitext += '{{teacherbox{\n';
ending = '}}}}}}';
break;*/
default:
wikitext += '{{teacherbox{\n';
ending = '}}}}}}';
break;
}
// Adding header or title
switch (this.elemtype){
case "theory":
case "example":
wikitext += '!{{teacherTitle{'+(this.title!==''?this.title:EbookDictionary.localize(this.elemtype))+'}}}\n';
break;
default:
break;
}
wikitext += '{{orderableelems{\n';
for (var i = 0; i<this.elements.length; i++){
if(this.editable && this.elements[i].type =="emfuncgraph"){
wikitext += '{{ebelement{\n' + elementFunctions['getWikiemfuncgraph'](this.elements[i].data,' author') + '}}}\n';
}else{
wikitext += this.elements[i].getWiki();
}
}
wikitext += '}}}';
wikitext += ending;
return wikitext;
}
EbTeacher.prototype.show = function(){
var teacherElement = this;
var pagenum = jQuery('.bookpage').index(this.place.parents('.bookpage'));
var tiddlername = this.tiddlerName;
this.place.empty();
wikify(this.getWiki(), this.place[0], null, store.getTiddler(this.tiddlerName));
if (!this.editable){
this.place.find('.teacherset:last a.button.command_qededit').remove();
if(typeof(Teachertool)==="function" && pagenum === 0){
var teachertoolbar =this.place.parents('.teacherbox').eq(0);
if(teachertoolbar.length ===0){
teachertoolbar =this.place.find('.teacherbox').eq(0);
}
if(teacherElement.elemtype ==="assignment"){
}
teachertoolbar.prepend('<span class="teachertoolbar"><button title="'+EbookDictionary.localize('edit teacherelement',pagenum)+'" class="teacherEdit ebook-button">'+Ebooksvgicons['edit']+'</button><button title="'+EbookDictionary.localize('delete teacherelement',pagenum)+'" class="teacherDelete ebook-button">'+Ebooksvgicons['trashcan']+'</button>'+(false && /*Remove when fixed */teacherElement.elemtype ==="assignment" && store.getTiddler(teacherElement.tiddlerName ).data('teacherdata').published == 0 ?'<button title="'+EbookDictionary.localize('publish',pagenum)+'" class="publishbutton ebook-button">'+Ebooksvgicons['publish']+'<span>'+EbookDictionary.localize('publish',pagenum)+'</span></button>':'')+'</span>');
teachertoolbar.find('button.publishbutton').click(function(){
jQuery(this).parents('div.ui-accordion-content').prev().find('button.publishbutton').click();
});
teachertoolbar.find('button.teacherEdit').click(function(){
teacherElement.editable = true;
teacherElement.editElements();
var t= new Teachertool();
t.tiddlerName =tiddlername;
t.oldContent = store.getTiddlerText(tiddlername);
t.teacherElement = teacherElement;
t.startAuthoring('edit');
teacherElement.hasTool = t;
teacherElement.show();
});
teachertoolbar.find('button.teacherDelete').click(function(){
if(confirm(EbookDictionary.localize('sure delete teacherelement',pagenum))){
var t= new Teachertool();
t.tiddlerName = teacherElement.tiddlerName;
t.startAuthoring('remove');
}
});
}
} else {
if(typeof(Teachertool)==="function" && pagenum === 0){
if(!teacherElement.hasTool){
var t= new Teachertool();
t.teacherElement = teacherElement;
t.oldContent = store.getTiddlerText(tiddlername);
t.tiddlerName =tiddlername;
t.startAuthoring('edit');
teacherElement.hasTool = t;
}else{
teacherElement.hasTool.editelem();
}
}
if(this.focusFirts){
this.place.find('.mathquill-editable,.command_qededit').first().focus();
}else{
this.place.find('.solutionelement .mathquill-editable').last().focus();
}
}
}
config.macros.teacherelement = {
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var sol = tiddler.data('teacherelement', {"creator":"","teacherelements":[]});
var editable = (sol.creator == config.options.txtUserName) && sol.editable;
jQuery(place).append('<div tiddler="'+tiddler.title+'" class="teacherElementsetwrapper"></div>');
place = jQuery(place).find('.teacherElementsetwrapper:last')[0];
var teacherElement = new EbTeacher({"tiddlerName":tiddler.title, "place": place, "editable":editable});
teacherElement.initElements();
teacherElement.show();
testilogit.tookko = teacherElement;
}
}
//}}}
//{{{
config.macros.teacherAssignmentAccordion = {
/**********************************************
* Show listed sd assignments in three accordions by their level.
**********************************************/
handler: function (place, macroName, params, wikifier, paramString, tiddler)
{
var $tiddler = jQuery(place);
var page = jQuery(place).parents('.bookpage').attr('id');
var pagenum = (page ? ['pageOne','pageTwo'].indexOf(page) : null);
var accordianElement = 'teacherAssignmentAccordion';
var defaultlang = Emathbook.options.pages[pagenum]["defaultlang"];
var pagelang = Emathbook.options.pages[pagenum].lang;
$tiddler.append('\n<div class="'+accordianElement+'"></div>\n');
var edata = {};
for(var i=0;i<params.length;i++){
var toUseTiddler = params[i];
//alert(params[i]);
// if (typeof(store.getTiddler(toUseTiddler).fields.ebooktitle) != 'undefined'){
var additional_title = store.getTiddler(toUseTiddler).data('teacherelement').title;
var pre_additional_title =' : ';
// }else{
// var additional_title ='';
// }
// if (additional_title.substring(2,9).toLowerCase()=="tehtävä" || additional_title ==": "){
if (additional_title.length==0){
pre_additional_title="";
}
var assnumber ='<span class="teacherAssignmentNroPlace"></span>';
var html='<h3 tiddler="'+params[i]+'"><a href="#">'+EbookDictionary.localize("assignmentTexture",pagenum)+' '+assnumber+'<span class="preadditiontitle">'+pre_additional_title+'</span><span class="additiontitle"></span></a></h3>\n<div>\n<div tiddler="'+params[i]+'" class="assignment_text assignment_text_'+params[i]+'">\n</div>\n<div tiddler="'+params[i]+'" class="emptySolution assigmentSolution assigmentSolution_'+(params[i])+'"></div>\n</div>\n';
$tiddler.find('.'+accordianElement).append(html);
$tiddler.find('.'+accordianElement+' div.assignment_text_'+(params[i])).append('<span class="assignmentId">'+params[i]+'</span>');
wikify(additional_title,$tiddler.find('.additiontitle').last()[0]);
}
$tiddler.find('.'+accordianElement).accordion({
collapsible: true,
autoHeight: false,
active:false,
change:function(event,ui){
var assignmentIdspan = ui.newContent.find('.assignment_text .assignmentId');
if(assignmentIdspan.length > 0){
var assignmentId = assignmentIdspan.text();
wikify('<<tiddler '+assignmentId+'>>',assignmentIdspan.parent()[0]);
var assignmentTiddler= store.getTiddler(assignmentId);
//if(store.getTiddler(assignmentId).data('assignmentType') === '0'aa.data('teacherelement').elemtype){
if(assignmentTiddler.data('teacherelement').elemtype && assignmentTiddler.data('teacherelement').elemtype ==="assignment"){
if(typeof(Teachertool) == "undefined" && typeof(Authortool) == "undefined"){//Remove comments when ready
wikify('<<showSolution>>',ui.newContent.find('div.assigmentSolution_'+assignmentId)[0]);
}else if(typeof(config.macros.studentsSolutions) != "undefined"){
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(assignmentId+'_'+pagelang)){
solutionAnswer = store.getTiddler(assignmentId+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(assignmentId).data('assignmentSolution',"");
}
if(solutionAnswer !==""){
var assignmentSolutionPlace = assignmentIdspan.parent().append('<div class="teacherassignmentSolution"><button><span class="hideTeacherAssignmentSolution">'+EbookDictionary.localize('close')+'</span> <span class="answerString">'+EbookDictionary.localize('answer').substring(0,EbookDictionary.localize('answer').length-2)+'</span></button><div class="assignmentSolution solutionAnswer"></div></div>').find('.assignmentSolution');
wikify(solutionAnswer,assignmentSolutionPlace[0]);
assignmentSolutionPlace.parent('.teacherassignmentSolution').addClass('hidden');
assignmentSolutionPlace.parent().find('button').click(function(){
jQuery(this).parent().toggleClass('hidden');
});
}
wikify('<<studentsSolutions>>',ui.newContent.find('div.assigmentSolution_'+assignmentId)[0]);
} else{
var solutionAnswer = "";
if (pagelang !== defaultlang){
if(store.tiddlerExists(assignmentId+'_'+pagelang)){
solutionAnswer = store.getTiddler(assignmentId+'_'+pagelang).data('assignmentSolution',"");
}
}else{
solutionAnswer = store.getTiddler(assignmentId).data('assignmentSolution',"");
}
if(solutionAnswer !==""){
var assignmentSolutionPlace = assignmentIdspan.parent().append('<div class="assignmentSolution solutionAnswer"></div>').find('.assignmentSolution');
wikify(solutionAnswer,assignmentSolutionPlace[0]);
}
}
}
assignmentIdspan.remove();
}else{
var assignmentId=ui.newContent.find('.assignment_text').attr('tiddler');
}
}
});
var bookpageElem = $tiddler.parents('.bookpage').eq(0);
var bookpageNro = pagenum || 0;
if (bookpageElem.attr('id') ==="pageTwo" && $tiddler.parents('.ebookopening').length > 0){
bookpageNro = 0;
}
var currpage = EbookPages[bookpageNro].currentpage;
if ($tiddler.parents('ebookopening').length > 0){
currpage = EbookPages[bookpageNro].ebook.tocdict[currpage].next;
}
var sectionNro = EbookPages[bookpageNro].ebook.getNumberedTitle(currpage).split('.')
var teachersnroPlaces = bookpageElem.find('.'+accordianElement+' span.teacherAssignmentNroPlace');
for (var i=0;i<teachersnroPlaces.length;i++){teachersnroPlaces.eq(i).append((i+1));}
}
}
//}}}
!usage
{{{[img[toctext.gif]]}}}
[img[toctext.gif]]
!notes
//none//
!type
image/gif
!file
./toctext.gif
!url
!data
data:image/gif;base64,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
!usage
{{{[img[toctext.png]]}}}
[img[toctext.png]]
!notes
//none//
!type
image/png
!file
./toctext.png
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAACwCAYAAAARzX5GAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAJwgAACcIB1cBiiwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABbFSURBVHic7Vx5VJPXtt8fISEgAZV5kEECIhCQQTDEgIBebBWRyZkHKlpFe1+dWm9vJ22r1FarcvFa7UP0grS2FhyogK2CQEEQHKhEVAYhgCGAhCFAAuz3h8BDyQlBe+96f3Svddbiy9nf/p19zt77TPuDQkQYjzw8PLju7u4xBgYGhtra2gY0Gk2zu7u7TSKRtFVWVpZduXLlK0TsUyoEEYkFALTXrVt3IT8/X4IEkkgkeODAgbtBQUErlMpSVhkVFXVaLpeTMF6g8+fPV3E4HJsJA7m7u78pEAi6VUIZou3bt6eT5KmTutTKyopnb2+vVVFRIU1LS7spFotrOjo6JHK5vB8RB9XV1dUZDAbTyMjIjM1mcyIjI22sra3ZJHlEIAsLC7Pm5ubB9evX7y4sLIxXNs46Ojp6QqEww9HR0ZaiKB1E7HiZR430MpPJ1BIIBF0VFRWXlIEAAHR0dLQ2NTXVm5iYaAOAniIeokZCofApn8/X2bhx4xkej5d669atazKZrAUA+gBgEAAYAKBlb2/v7OLiEvTXv/7V5/79+08BoG5CQDU1NXV9fX3w5Zdf8js7O/mVlZW9zc3NnT09Pf0DAwPIZDLVWSwWg81mTzY3NweKoqCgoKAQEQcUCiSaI4B2XFxcmaoW19DQIA8LC9s2YfNGRODz+X85d+6caDwQkUg0uGHDhh+UyaJwnBDk4OBgN3fu3D18Pt935syZBlZWVuqTJk2Curo6qK6ulpSWlj7Mz8//V1ZWVgIiDpLkjAs0wkhRGtra2pYcDmcWg8GYWldXd6empuYRIraqJECZuhMpPj4+/MWLF39BjAwURRmr1KJxKDIycu2sWbPmAMB7iurVY2NjS0JDQ6e8LpCRkRE9Ozu7ilSv7uTkhAEBAZNeFwgAIDs7m1hHDEF/NKkDAIhEIujp6XktQZMmKe8UdQCA9evXp9TX1ye9DhCHw9ns5uY2k8gQFBR03N3d3e0PMO+gJUuWnHzlyAAAQFGUnrm5uZO1tbWrvr7+lNbW1pu5ubk/j6rXBgBzAHiMiP0KhShrJYvFmrpq1aoTKSkpjQ8fPkSZTIaIiJs2bUoYzWdiYuJ96tSpnsDAwHeIDqtMk7Vr1549dOhQII1GU6pxU1NTKZ1Ob3F3d18IAIcV8RDN28/PL2r37t3+44EM9UqfRCKRWFlZsSmKUth4okZsNtvdxMSE/uuvv7aVlZVVdHd3t4nFYu09e/b4v8xLUZTayZMnmTNmzDAAABMAqFcZSF9f36C8vLxv69at0QKB4BIAgJub28Kenp4xQObm5k4eHh4WMplMDs+n+DFE7Lqurq4OAwMDuoGBgT2JBwCAxWLpL1u27J/Ozs70yspKEQA8UcRH1Kiurk5obGysdvr06b1ff/31qs7OziZvb29NTU1NMDMz4+7Zs+eChoaG7pkzZ+yDg4ON1NTUoK2trXHC5u3q6jrr8uXL4vGm8WHq6enBiIiIeJI8pX60ZMmSA+3t7YOqAO3du7cQADRfCQgAaKGhoV8kJiZWkRb7paWlki1btvzk4uLiokyWqiFId+HChbGmpqZG+vr6enQ6XaOtra1VJBK1VVdXX7l9+3b+uEKUtULVAgCa/v7++319ff1IPETznjNnzvuJiYkN8+fP/3Dc1gL0hoaGLuPz+e+TGJQt8unr1q0zZbFY48cgAIqiKDmbzXagKEpDEcMLfsRms83MzMzmAwB0dXW5AAC0trY6+fr6RpEQ6HS6dnR0ND8sLMy2vr4eAWAaADxWCmRgYLAkJSXlmLa2NlAUBQAAly5dCkPEMBIQg8EALS0tAAAQCATdAKBwTfACECKilpYWTJ48eeQ3XV1dEsYYEggEIgBoVFj5kvVMCgsLO5SSkvJkcFAlPx2hvr4+XLly5bEJ+ZGpqak5n88/npKSsujixYvivr4+GUmLwcFBbG1tbS0pKbmRnJz8LiL2jqvR6KKnp2dz/fr1zsWLF38KAEwlhaGKrxGjd0tLS9XKlSsvSaXSB8RWToCIfuTt7e3DYrFaKIpSPLijiKIorbCwsAcrVqxImDAQg8HwO3HixNssFst3PCBElPr4+PR7enr6TBhoImRhYWFnZ2dnyOFwLCmKMlLE88IYubu7Lw0LC9vBYDAGfXx8pgIAeHh4hH311Vd+JBCKohjx8fG2Cxcu1Ltz584gg8GYDACiMYyjLWPOnDmbOzo6JuQ/o+n7779vBgAtRVb3QtfJZLIHycnJVf39iqf98ai8vLwSEaUKK19GZrFYU5cvX34iPT29aSLa/PDDD4/9/f3fIPkRcYblcDirsrKyknfs2JHDYrF+J2mBiINCobBNIBAk1dbWKjyeUajRcAEAjS+//LIuODh4D4lnIoUYGRCxz9DQMLi7u7sR4PnMBgBGQ0WMiOM6skoaDZd58+ZF/f3vf8+Lj49/nJmZ2VZRUYHR0dEnRvMYGRnxd+7c+YDH4wVPWCMAgDVr1hxPTExca21t/cJ6mslkykc/i0Sicm9v7ylyuTwSAC4okkWMDJ6enj7vvPPOspdBCL3SLhKJntnY2BD3sESN7O3tl3h4eEyRSCSQm5vb0tjY2N7T00Nt2LDBhgA2OGPGDGOKoowQcUxkIAIZGxsbNTU1DS5btuxQfn7+PkR85ubmtjA8PPzKy7yamprmmZmZFiwWSx0AdEFBCCJ23cDAQH9ra6tcLBZfQcRnJD6Koqjg4OA4T0/PSVVVVS0AIFTER9SooaGhwcnJSWPfvn2JO3bs+K25ublRR0fHTE1NDbq7ux1XrVq1n8Vi6e7bt89p48aNPE1NTWhubm5UOQQNFy8vryX379/vnUgY2rRp0/fEAKDMhyIjI88PDAyoBJKcnPxo2rRpVq8ExGKx9LZs2XKloqKihwQglUrx8OHD9954443VymSptG2ZO3dukJeX10o9PT19FoulR6PRNLq7u1slEknr77//fvfChQsHEFHpqZXKZ6qvS3/YeV1AQMBfli5d+g9SPdG8Z8yYYTNlypQAVYGmT58e4uHhYTlhIBMTkzWZmZmfqApEo9EgPj5eMGEgAAAmk6kqzrj0nz1TJVFnZyf88MMPTQCg1DS1tbUZZmZm9OLi4rHruWEiOZivr+/HR48ebQYAljJHRETw8/PbmJ6e3u7g4EA8MlUaFYyNjTnjgQz5oXFGRkb71q1b/0XiIXZdR0dHKwCodMHh4eHh5+DgoNXQ0DCHoigGIo7ZuBGBOBwOZ8qUKSHKAGg0Gtjb25tv3LiRa2VlRffy8rLS1NR0AIA7KgPp6emF5uTkfKJclxdJU1OTpqenp3B3/Yea9717954KhcLyfytQR0cHXrhw4RIitimqV+pHEokETp06VUNRFNGPBgYG+qRSqaisrOzXtLS0/WfOnFHIpxToxx9/FG3bts0FETuV8alEJLs3NTU1s7GxmaeKHyEisNlsU2dn54UT9qOGhoYGAGhQtcGenp7v2travgEAMxTVqy9fvryYx+NRE++LFykkJMSwrq6um8hw7NixOtLCY6J08ODBClLX/cemif/sfLRhw4ZcuVx+63UE6enpcc3MzMjXrBERETd4PF6YqmZMKgsWLPjv0NDQPFL9K6/rKIpSZzAY02UyWSMido3LTwKysrIyMjEx4Q0/t7W1FVZWVjZRFKUZHR19lM/nz3d2djarqalpu3fv3sPMzMxPS0pKrhKRSKoGBQV92NTUhE1NTZiVldXn7e39NiJCVFTUj319fWNM+/Lly+JZs2ZxSfKIQJs3bz6GiBgbG5tlZWXlDQCUi4tLUGVl5ciCXyaTYVJS0pOioqJORMRt27ZdnjDQzp07U0tLS6XW1tYew79t2bIldbQWf/vb324AwCQnJyfu8ePHK7755puq4eFQ2WHpdLpWUVFRY3V19a2hwWe6ubl5DNcLhcKBa9euHUHE7vLy8kKBQFBiY2NjAM8PPMYQEUgmk7VzOBxjS0tLWwCAN998c2dERMRIJlN6enrFzZs304afnz171qyvrz+JTqcr9CVi9H7y5InQ09Nz0ltvvZUSExNTsXXr1kAWizVSf/v27QIclWNiamrKaWlp6ZDL5RKFAkljxGKxpiYlJdWMMS9ETE1NrXFycrIccg01T0/PmHv37nUmJCQ8BMIYjeft0T/99FP98Kl+f38/JiUlVYeFhS1DRODxeCsPHTp0/8GDBzJExL1792aTZI0bGWxsbGY4OTlFmJiYGAqFwvrKysqUR48eNQIA8Pl8P2dn52WjuvvG5cuXUyfUdd7e3iujoqLSlGk8kUKs8PX1/fjx48eytWvXnnV1deX9W4GGx6a4uFj6wQcf5AYGBr4LSq5AXxmooKBAunTp0m+PHDlSVl9f3y+RSPDYsWOPoqKiEmfMmDGhrA5ihZeX16bVq1dfHzIWisvlhmzbti317Nmz9VKpFPPy8jree++9qz4+PlsBQOOVgYgvAOgEBQW9v2vXrhv37t2Tt7a24uHDhytWrFhx3MzMzP4PA7Kzs3Nbt25d0unTp2t6e188k8rOzm7btm1bBpfLjQQANVW7Lmb16tVZQ1rQ+Hx+zLvvvptVUFBAvFPo6OjA2tpaeUNDQ//nn39+KyAgYI1KxlBYWNgdEBBw8osvvrjz9OlT4jGXQCDo+fzzz68vWrTobS6XG75r166MsrKyrurq6p7IyMhvxwXq7+9H0mX8wMAAXrx4UbR9+/ZULy8v/5ff5/F4C/bv318mFov7ly9fvlfpbkJRYsuzZ88gNTX1fmFhYXZmZuYBsVj8VNG7+fn5V62traudnZ1vubq6+ikFGk13797tSU9PLywqKvopMzPzBCLKx3untrb2iVAobNXT05umFGhwcBDS09ObcnJycoqKio4XFxffULVhwcHBBz777DOfFStW2CQnJz9QdjcBCQkJzR9++CG3vb1dYcKKMqLRaM5yubzn0KFDOQKBoE6ZY+oCwHRV/euVN2KIKAEAxdOyAvpzI/Zvoz83YsQy3kZM/dy5c8SL9IlQX19fmYaGhimp/s9cYqX0Zy7xK9H/m1xi9YsXL256HU2GSUtLy1xDQ2M6qX7cNYO9vb2bra3tImNjY31qOHNMAbm6unro6+tPJtUPz6Y0AGADgPpodUNCQv6Wm5srUfXmUuk0QVEUMzY29lpJScndXbt25QylVIOJicm0mJiYbT4+Pjpqan+AF3A4nKD6+npEROzu7kYulxuDiBAREbFfVU1U0Ui9urr6ZkZGRu1bb71llZaWJmxvb/8VAMDY2FhfTU0Nnjx5Mnj16tXa9vZ2oVQqpcXExHATExMFTCZz5IKku7ub6e7u7picnPzj9u3byWPk6OjoHBwc/NGsWbNch1vw3nvvnZVKpbhgwYIvAIA2NJY2RUVFveHh4ftGtxYAtM6cOVMXHR19ijhGAAAsFstw6tSpUw0MDEbCvEwmoy5evCi+evXqp/h/3xR1dXZ2yoyMjIxfaqxULBa3uLu7zyHle4Ourq5FampqIyJidnZ2q6OjozMiQmxs7Knc3FyphoaG5aiW05OTk59euXJFOH/+/LcAwMTY2Jjt7+9/8NGjR315eXndAGChSCNwcnIKrK6uHkBEbG9vR09Pz/9CRIiMjPyqt7cXly5dGjf6hYSEhEpERJFIhNnZ2R0FBQXS4Vz9vLy8HiIQAKhFR0ennTt3rnHz5s2XYMiXAgICtvX29uL169dbdu7c+auLi4sbIsLu3bu/I1ndyZMna4FwRKOOzw+OQiiK0kJE6bFjxwAAoKqq6toHH3xwRVtbW06n02mDg4NTAADu3r37fUlJyYLZs2dPHT0EAwMDUFRUdAOHm6/I6iZaFi9evOXo0aPleXl5XY8fP8a0tDRxTEzMj7q6upNJ77zW7b+urq715MmTrevq6n5HxGZlvK8UWyiKojs6Or7p6+sbaWZmNg2ex0rl75A04nK5nhwOZ83wc0VFRUp+fv5NLpfrFBgY+M+YmJi55ubmIJFI4JdffmlKTEz8n4yMDHImNalPIyIi9iIiNjY2yuPj4wU8Hi8MABi7d+/OV2Rx1dXVsnnz5kWR5BGB3n777ZMymQxDQkL+CUMhiM/nb21vbx8RLhQK5R999NEvX3/99e8dHR34ySef5JPkESc+JpOpe+3atWeZmZkjIYjH470xOon5448/Tvv222+XURTFkEqlOZaWlhYURamjgk8alOWpMmpra9t6enqaAAAMDAyMuFyu+3B9WVmZ9MaNG18Mdb/syZMnd+zs7Azh+edBY0jZlyBiHx8fSwcHhwUAAP7+/gcWLVo0cqadnZ19++HDh6XDz/39/f1MJpMGE/3k5OHDh7+bmJiox8XF/evTTz8t2r9///LhA47e3l64detWzjAvRVGUjY2NZ0NDwzMgXeQTrQRA/aOPPipVZGFxcXElMHRGZ25uPnvx4sXJYrG4/8iRI+UTNgZE7HdwcPgvmUx2Mjw83NXKyoopEAik6enpxbm5uZsQsW/u3Lk7k5KSPnVzc2NSFAVCobCaJG/cEERRFKWvrz+TzWZzioqK8hFx5G7W0dHRSl9ffySpuaurq7S0tFRxqumrBFVFZf78+bHBwcE5xK6jKIry8/PbbGhoaPXo0aPvS0tLSwEAPD09XadNm6Y0cWI0sdnseba2tvpEhlWrVh0Xi8X9iIjnzp2rd3d35yI+P69TZAjKSOkC0svLy09fX58GABAREWHu6uq6jNiq1yC1tra2luGHzs5OaGxsJOf2vAap5+XlffjZZ5/tMzY2NsrLyyv8+eefDw5XPnv2DM6cOVNOo9HGnR0tLS0Vfrg+QqMc9IXjY19f348TEhKaAGCSKla3Zs2aw3FxcQJSPfFFCwsLY3t7e+J158vFxsbGytnZeRWp/pXWDEOf/kxCQiKLwndUBaIoihYaGrrPzc3N18LCYtrUqVM1a2pqmhobG2t++eWX/cXFxQXjAoWEhBzi8XgLhn9sbW2lp6SkbKyrq7sxBMLcvHlzRlxcnJ+Ojs6YXV9eXp44ISHhyHffffc5EQkRYc+ePT8jIra1teH58+fF77//fpG5ubnzcP+uXLnym5fvIRAROzs7R/6+dOlS08yZM+2UGkN8fPw9uVyOwcHBpwFA96VBdsrJyWkdDXDjxo2WtWvX/mP27Nlrly5deiAlJaUKETE2NvY7IhAAqJ06dUp49uzZegCY8jLD+vXrT4wGEYlEA4sWLdo9msfb25v/22+/SY4ePVpGDEEAoKOnp8cUCoW1+FIWNEVRdHd397mjfzt16lR5RkbGl6N/KygoyLt69epNHR0dA4qiFC4m1QCATqfTobu7e8wUPHv27FVhYWEjX48iIpSWluaign/20NXVJWKz2foAYEYCaqmvr5doa2uPCSE8Hi/M0NBwxMpycnI6CgoKjisSNDg4OKitrc0AAC2FQIiIXV1dbR4eHg62trYOwxXz5s3zCw8Pf6HbsrKyihsaGhTmourq6pp2dnZKAUBhvrcaAEBVVVX1vHnzpkZHR58JDAzcFRYWtnfjxo3xPB5v5MBQJBIN3Lx585wiIdOnTzfncDguNTU1bQCg8JoHEBFmzZrF/e233zoQn19A9ff3j/GZHTt2ZAJhN7dmzZrzg4ODePDgwRKS1akDANy+fbtw9erVyUZGRmunT5/+QrqtTCaDw4cPl127du1tHHIIiqI0w8PD99rZ2U03MjKyPnDggBNFUdDU1ERcBY0st1JSUmKXLFlS6enpucTIyMhKQ0NDXSwW1965c+d+cnLyTnwx136Kj4/PJj6frz3UrdDQ0AACgaCMBPS/bZyZynxxYewAAAAASUVORK5CYII=
!usage
{{{[img[toctext_sv.png]]}}}
[img[toctext_sv.png]]
!notes
//none//
!type
image/png
!file
file:////home/pesasa/gitrepos/imped/ebook/toctext_sv.png
!url
!data
data:image/png;base64,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
!usage
{{{[img[uppage.png]]}}}
[img[uppage.png]]
!notes
//none//
!type
image/png
!file
!url
!data
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAANgAAADYABpllopAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAFTSURBVDiNrZS7TgJREIa/s9nFeKGhsaLDaMTCBGG5tJSGxpDIQ5hY0dtYWMlTaLKh8x1YFkksxGi0o7KGKAo5x8LdAiK7Zw1TzZnLN/+cYoRSilWasVKaLtDplFNOp5zSqTW1pgp14btnUbUi6g/bvUJWSeMBQBjy8CTvDUKHR02U0rjmdxPT90MtFOi4pZqAavAWUHXcUi2sZ+nKztNBQoy2BkBmIfWmkuNsff/xO5ZCMd48/wMGkPFz+gpvusVtC16B5JK+0RR2Grb7rqXQgssQGEDSr4lW6HSLOQE9QIQAAZSCfN12+1EKWxow/JrWYnAO2PbshoCKBiwgVtqe3ZiLBSvf9Y82vmbms4K0LtCHDtfM2d5x7v5jTuFkajXjwgAUpCdTqzmn8LZXSJvSeAHW4wJ9+5wZcvc07w1NgIQ0MlKJq3/CCBjAMPLaxLWVX+wfjilv8AfhYjAAAAAASUVORK5CYII=